1.流程
首先在用户打开小程序的时候,通过wx.openSetting
判断用户是否已授权,如果没有授权的话,显示button按钮
下面是wxml的相关代码
<button open-type="getUserInfo" bindgetuserinfo="allowLogin" class="wsy_allow_btn">允许</button>
在这里按钮有一个attribute为open-type,open-type的值设置为getUserInfo的话,就可以获取用户信息,可以从allowLogin回调中获取到用户信息
下面是js的相关代码
allowLogin(e) {
if (e.detail.userInfo) {
this.triggerEvent("sendInfo", {
userInfo: e.detail.userInfo
});
} else {
this.triggerEvent("sendInfo", {
userInfo: null
});
}
this.triggerEvent('changeFlag', {
bool: false
});
this.login()
},
因为在我的项目中,登录模块用了一个单独的组件,所以在这里获取到用户信息,要把信息通过triggerEvent
调用自定义方法,传值给父组件
在进入这个allowLogin
回调后,需要调用wx.login()
获取临时登录凭证code
,拿到code
后,就可以去请求后台接口,携带参数code
和用户信息,后台调用微信接口用code
换取session_key
,后台会用session_key
解密数据,获取到openid
和unionid
那么在这里,衍生出了一个问题,就是调用wx.login()
会刷新session_key
吗?
下面是我连续3次测试的结果, 可以看出三个不同的 code 得到相同 session_key:
| code | session_key |
| - | - |
| 061AlTTl1NN1Xk0ZmcUl1iZ0Ul1AlTTi | eTVWziFnhu2vG+iVrjDOqA==
| 071Rl0SD0Dd7Sc2hkkOD0asORD0Rl0SW | eTVWziFnhu2vG+iVrjDOqA==
| 071wl53j2qtQCH0SfKZi2SVN2j2wl53d | eTVWziFnhu2vG+iVrjDOqA==
我决定等待10分钟之后再去尝试:
code_xxx LMiKHyNLaGHidXqSsg4Ung==
果然 session_key 发生了变化,这和官网文档说明符合:
原文:微信不会把session_key的有效期告知开发者。我们会根据用户使用小程序的行为对session_key进行续期。用户越频繁使用小程序,session_key有效期越长。
好的,这个问题解决了,那么通过session_key
获取到的openid
和unionid
又是什么,有什么作用?
我去看了下微信开发文档,于是有了如下答案:
openid
在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的。对于不同公众号,同一用户的openid不同)。——微信公众平台开发者文档
- 普通用户的标识,对当前公众号唯一
- 不同的公众号,同一个用户,openid不同
你可以简单的理解为
openid = hash(uid + app_id)
unionid
如果开发者拥有多个移动应用、网站应用、和公众帐号(包括小程序),可通过unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号(包括小程序),用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。UnionID机制说明
如果开发者在多个移动应用、网站应用和公众帐号之间有统一用户账号的需求,需要前往微信开放平台(open.weixin.qq.com)绑定公众号后,便可利用UnionID机制来满足上述需求。
- 一个微信开放平台帐号下可以有多个移动应用,网站应用,公众账号和小程序
- 只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号(包括小程序),用户的unionid是唯一的。
也就相当于是用户在开放平台的唯一标识符
你可以简单的理解为:
unionid = hash(uid + 开放平台id)
微信针对不同的用户在不同的应用下都有唯一的一个openId, 但是要想确定用户是不是同一个用户,就需要靠unionid来区分。一般自己的后台都会有自己的一个用户表,每个用户有不同的userid。也就是说同一个用户在同一个微信开放平台下的相同主体的应用对应着相同的userid,unionid以及不同的openid。所以在用户登录进来的时候,我们只能靠微信返回给我们的unionid去判断是不是同一个用户,在去关联我们的用户表,拿到对应的userid。
在拿到openid
和unionid
之后呢,需要数据库去比对当前用户是否存在,如果不存在,就需要注册新用户,存在的话,会生成一个自定义token返回并通过接口返回,在小程序中,保存token
wx.setStorageSync('token', data.data.token)
接下来就是可以用token请求其他接口,在请求接口的时候判断token是否过期,如果有效的话就可以继续操作,无效的话清除本地存储的token,再调用wx.login()
获取临时登录凭证code
,然后调用wx.getUserInfo
获取用户昵称等,请求后台接口,携带参数code
和用户信息,上面说过的操作
上面我们说的是用户没有授权,需要调用授权按钮
那么用户已经授权了呢?已经授权的话,就需要判断本地有没有token了,存在的话,可以请求接口,不存在就是上面说的操作
总结
其实小程序中的授权登录,看似复杂,之前我也是感觉非常困难,难得一批,但是梳理下来之后,就发现,也还可以
总的来说有三个分支,1.判断是否授权2.判断token是否存在3.判断是否为新用户
本人理解就是这样了,如果有不对的地方,欢迎大佬们指正,后期的话,发现新方式或新方法,再来续更
小伙儿不容易,喜欢本文的话赐个一件三连吧