vue授权码模式登录,vue微信登录授权绑定
用户可以访问微信中的第三方网页,通过微信网页的授权机制获取用户的基本信息,从而实现所需的业务逻辑。本文主要介绍Vue3项目中微信授权登录优雅实现的相关信息,有需要的可以参考。
目录
前言
准备
实现理念
上部代码
摘要
前言
微信授权登录是微信微信官方账号开发绕不开的话题,整个授权登录过程的实现需要前后台的配合。在以前前端和后端没有分离的时候,也许我们的前端不需要太在意授权的具体实现。然而现在是2021年,前端分离的架构大行其道。如何在前端分离的情况下实现微信授权登录,成为了今天要讨论的重点问题。
准备
首先,我们还是要先梳理一下微信授权的全流程。这里,我就直接把公文搬过来:
如果用户在微信客户端访问第三方网页,微信官方账号可以通过微信网页授权机制获取用户的基本信息,进而实现业务逻辑。
.
解释两种网页授权范围的区别
1.以snsapi_base为作用域发起的网页授权用于获取进入页面的用户的openid,并且是静默授权,自动跳转到回调页面。用户感知到的是直接进入回拨页面(往往是业务页面)。
2.snsapi_userinfo作为作用域发起的网页授权用于获取用户的基本信息。但是这种授权需要用户的手动同意,并且由于用户已经同意,授权后无需注意就可以获取用户的基本信息。
.
具体来说,网页授权过程分为四个步骤:
1.将用户引导至授权页面,以同意授权并获取代码。
2.网页授权access_token的交换代码(不同于基本支持中的access_token)
3.如果需要,开发人员可以刷新web authorization access_token以避免过期。
4.access_token和openid通过网页授权获取用户的基本信息(支持UnionID机制)
这里附上微信微信官方账号开发的微信授权官方文档。
以上是作者摘抄的关键信息。当然,还有更多解释。希望新手读者先仔细阅读官方文件。
这里我再补充一下,上述过程中的四个步骤中,除了第一步,其他三步都需要在服务器端完成。前端需要做的其实是如何检查判断用户的登录状态,维护登录状态。
实现思路
众所周知,Vue是前端分离技术的产物,是纯前端应用(服务器端渲染除外)。通常,当用户打开页面,执行页面的js脚本时,我们异步请求服务器数据,然后进行相关逻辑的处理和判断。我们需要判断用户是否需要登录(cookie或者token)才能实现微信授权登录。当用户未登录时,需要授权登录过程。当授权登录成功后,我们还需要在前端记录登录状态,这样就不需要在页面切换时再次触发授权登录。通过重新分析可以看出,前端实际能做的是获取微信服务器给我们的代码,然后把代码给我们后端,让后端完成后续的步骤,获取用户信息,生成用户。然后我把整个过程梳理如下:
(前端)检查用户是否登录;
(前端)如果没有登录,引导用户到授权页面,同意授权,获取代码。
(前端)将获取的代码提交给后端。
(后端)通过代码交换用户凭据openid
(后端)通过openid检查用户是否存在,是否需要注册新用户,获取用户id。
(后端)返回用户信息;
(前端)记录用户的登录状态,跳转回登录前的页面;
这个过程,我画了一张图,如下:
上代码
按照上面的思路,现在开始编码。作者用的是Vue3,Vue2的开发者要根据情况适当调整。
为了方便的唤起用户的授权登录逻辑,作者打算将授权登录封为登录页面。这样做的好处是,我们可以在任何我们判断需要登录的地方,通过Vue路由器的push方式直接跳转到登录页面。
通常,并不是我们应用程序的所有页面都需要登录才能被访问。只有在访问特定页面时,用户才需要登录,所以我们需要识别哪些页面需要登录认证。这里我们可以用Vue路由器的meta属性进行识别。官方文件对meta的解释如下:
有时,您可能想要将任意信息附加到路由,例如转换名称、谁可以访问路由等。这些事情可以通过接收属性对象的元属性来实现,在路由地址和导航卫士都可以访问。
正好Vue路由器官方有个例子,如下:
常量路由=[
{
路径:“/帖子”,
组件:PostsLayout,
儿童:[
{
路径:“新建”,
组件:PostsNew,
//需要登录才能访问的页面
meta: { requiresAuth: true }
},
{
路径:“:id”,
组件:PostsDetail,
//任何人都可以访问的页面
meta: { requiresAuth: false }
}
]
}
]
接下来,我们可以在Vue路由器的全局卫士beforeEach中获取这个元信息,进行登录跳转。
router.beforeEach((收件人,发件人)={
//而不是检查每个路由记录
//to . matched . some(record=record . meta . requires auth)
if (to.meta.requiresAuth!userStore.isLogin) {
//此路由需要授权。请检查您是否登录。
//如果不是,重定向到登录页面
返回{
路径:“/login”,
//保存我们现在所在的位置,以便我们可以稍后再回来
查询:{ redirect: to.fullPath },
}
}
})
需要补充的是,userStore.isLogin的实现与我们实际采用的登录维护方案有关。如果采用令牌,则检查令牌是否已经存在。本文使用vuex保存令牌,然后借助插件将存储中的数据持久化到localStorage。
接下来,我们来看看具体的实现:
登录组件
模板
div class=login/div
/模板
脚本语言
从“vue”导入{ defineComponent }
从 @/hooks/useWechatAuth 导入{ jump2Auth,getUserInfo }
从“@/store/modules/user”导入{ userStore }
从“@/hooks/usePage”导入{ redirectTo,getRouteQuery }
导出默认定义组件({
名称:登录,
setup() {
let code=getRouteQuery()。代码为字符串
//3.如果有一个代码,它已经被授权
如果(代码){
getUserInfo(字符串形式的代码)。然后((res: any)={
//记录令牌
用户存储.保存令牌(res.access_token)
const redirect=user store . userstate . land page route /
//跳转到授权前访问过的页面
重定向(重定向)
})
}否则{
//1.记录上一页的地址
const { redirect }=getRouteQuery()
如果(重定向){
userStore.setLandPage(作为字符串重定向)
}
//2.跳转授权
const callbackUrl=window . location . origin window . location . pathname
jump2Auth(回调Url)
}
},
})
/脚本
如您所见,登录页面实际上没有任何内容。跳转到这个页面后,我们会被直接重定向到微信授权的页面。当授权被收回时,我们也将返回到此页面。此时,我们将通过获取路由参数来获取代码参数。
@/hooks/usePage.ts:这个文件主要封装了路由器相关的常用方法。
从 @/router 导入路由器
从“lodash”导入{ cloneDeep }
从“vue”导入{ toRaw }
/**
*重定向
* @param path路径
*/
导出函数redirectTo(路径:字符串){
常量{替换}=路由器
替换({
路径,
})
}
/**
*获取路线上的查询参数
*/
导出函数getRouteQuery() {
const { currentRoute }=路由器
const { query }=currentRoute.value
返回克隆深度(查询)
}
@/hooks/useWechatAuth.ts:这个文件封装了微信授权的请求,以便与后端进行交互。
从“@/hooks/useAxios”导入{ useAxios }
/**
*获取微信授权的跳转地址
* @param callbackUrl授权回调链接。
* @返回
*/
导出函数jump2Auth(callbackUrl: string) {
useAxios({
网址:/API/微信/auth ,
参数:{
redirect_url:回调url,
},
}).然后((authUrl: any)={
if(process . ENV . node _ ENV=== development ){
window . location . href=callbackUrl ?代码=测试
}否则{
window.location.href=authUrl
}
})
}
/**
*提交登录代码。
* @param代码
* @返回
*/
导出异步函数getUserInfo(代码:字符串){
const userInfo=await useAxios({
方法: POST ,
网址:/API/微信/auth ,
参数:{
代码,
},
})
返回用户信息
}
@/store/modules/user.ts:全局状态存储,主要用于记录token和登录前的访问页面。
从“vuex-module-decorators”导入{ Module,VuexModule,Mutation,getModule,Action }
从“@/store”导入商店
从导入{ initialUnencryptedStorage }./全局
界面用户状态{
令牌:字符串
landPageRoute:字符串
}
const NAME=user
//名称:模块名称
//Namespace表示打开命名空间。
//当dynamic设置为true时,表示创建了一个动态模块,运行时在存储中注册该模块。
//preserveState如果数据是持久化的,当这个变量为true时,可以从存储中取出初始值。
@模块({
命名空间:对,
姓名:姓名,
动态:真的,
店,
preserv estate:Boolean(initialUnencryptedStorage[NAME]),
})
导出类用户扩展VuexModule {
用户状态:用户状态={
令牌: ,
/* *登录前访问页面*/
landPageRoute: ,
}
get isLogin(): boolean {
回归!this.userState.token
}
@突变
saveToken(token: string): void {
this.userState.token=token
}
@突变
setland page(route:string):void {
this . userstate . landpage route=route
}
}
export const User store=getModuleUser(User)
在vuex-persistedstate插件的帮助下,作者将数据存储在localStorage的store中。这样做的好处是,用户关闭页面后,可以再次访问,也就是不用再次触发微信授权流程,大大优化了用户体验。
总结
我不得不说,就代码抽象和重用而言,Vue3写起来舒服多了。希望你也可以尝试按照官方的做法,将逻辑代码解耦,逐个生成hook,这样代码看起来优雅很多。经过作者的尝试论证,该方案在整洁优雅的代码和业务需求的实现上近乎完美(请允许我装一波B)。当然,这里可能有我没有发现的bug或者痛点。毕竟从来就没有完美的架构。在此,也欢迎大家和我一起探讨,提供更好的方案和思路。
关于Vue3项目中微信授权登录的优雅实现的这篇文章到此为止。更多关于Vue3微信授权登录的信息,请搜索我们之前的文章或者继续浏览下面的相关文章。希望大家以后能多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。