小程序登录流程图(具体详情可看官网链接):
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html 小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系。
前端开发者需要做的任务是从小程序到开发者服务器这一条线路的工作。
开发者服务器到微信接口服务是后台人员的解密拿openid和session_key的工作。
1、登录流程解析
首次登录:
1、首先需要调用小程序api接口 wx.login() 获取 临时登录凭证code ,这个code是有过期时间的。
2、将这个code回传到开发者服务器(就是请求开发者服务器的登录接口,通过凭证进而换取用户登录态信息,包括用户的唯一标识(openid)及本次登录的会话密钥(session_key)等)。
3、拿到开发者服务器传回来的会话密钥(session_key)之后,前端要保存wx.setStorageSync('sessionKey', 'value')
再次登录的时候,就要判断存储的session_key是否过期了:
1、获取缓存中的session_key,wx.getStorageSync('sessionKey')
2、如果缓存中存在session_key,那么调用小程序api接口wx.checkSession()来判断登录态是否过期,回调成功说明当前 session_key 未过期,回调失败说明 session_key 已过期。登录态过期后前端需要再调用 wx.login()获取新的用户的code,然后再向开发者服务器发起登录请求。
3、一般在项目开发,开发者服务器也会对用户的登录态做过期限制,所以这时在判断完微信服务器中登录态如果没有过期之后还要判断开发者服务器的登录态是否过期。(请求开发者服务器给定的接口进行请求判断就好)。
4、无论是微信服务器过期了还是开发者服务器登录态过期了,都要像首次登录那样开始三步骤。所以注意封装代码。
wx.checkSession()详情了解:
https://developers.weixin.qq.com/miniprogram/dev/api/wx.checkSession.html
2、代码封装解析
通过上面的文字解析,我们把登录流程进行封装:
/**
* 用户相关服务 登陆,检查登录态
*/
const api = require('api.js'); // 这里是本人对统一接口地址封装
import {
HTTP
} from 'http.js' // 这个是本人对wx.request()这个api进行了封装
// 一般都把登录代码封装为一个类,然后export 类出去。当多个组件使用到的时候就继承这个类就可以使用登录接口了。
class USER extends HTTP {
/**
* Promise封装登录接口
* 判断本地缓存是否有sessionKey
* 有的情况下判断它是否过期
* **如果微信服务器没过期,继续从开发者服务器校验是否过期
* ****如果没过期,跳过登录,过期则调用登录接口
* **如果微信服务器登录态过期,则调用登录接口
* 没有则说明无登录态,调用登录接口
*/
login() {
return new Promise((resolve, reject) => {
let sessionKey = wx.getStorageSync('sessionKey')
if (sessionKey) {
console.log('sessionKey不为空')
this._checkWXSession() //检查用户的登录态在微信服务端是否过期
.then(() => {
console.log('微信后台未过期>>>开始检测开发者服务器登录态')
return this._checkSerSession() // 检查用户登录态在开发者服务器端是否过期
}).then(res => {
console.log('sessionKey校验通过')
resolve()
})
.catch((res) => {
console.log('sessionKey校验未通过,过期了')
this._wxLogin().then(res => {
console.log(res)
return this._serLogin(res.code)
}).then(() => {
resolve()
})
})
} else {
console.log('sessionKey为空,先微信服务器登录,再进行开发者服务器登录')
this._wxLogin().then(res => {
console.log(res)
return this._serLogin(res.code)
}).then(() => {
resolve()
})
}
})
}
检查微信服务器登录态是否过期的代码封装:
/**
* Promise封装wx.checkSession(),检查微信服务器登录态是否过期
*/
_checkWXSession() {
return new Promise((resolve, reject) => {
wx.checkSession({
success: () => {
resolve(true)
},
fail: () => {
reject(false)
}
})
})
}
检查开发者服务器登录态的代码封装:
/**
* Promise封装开发者服务器sessionKey,检查开发者服务器登录态
*/
_checkSerSession() {
return new Promise((resolve, reject) => {
this.request({
url: api.checkSession,
header: {
sessionKey: wx.getStorageSync('sessionKey')
},
method: 'POST'
})
.then(res => {
resolve(res);
})
.catch(res => {
reject(res)
console.log('后台登录态过期')
})
})
}
wx.login()微信登录接口api的封装:
/**
* Promise封装wx.login
*/
_wxLogin() {
return new Promise((resolve, reject) => {
wx.login({
success: (res) => {
if (res.code) {
resolve(res);
}
else {
reject(res);
}
},
fail: (err) => {
reject(err);
}
})
})
}
开发者服务器请求接口登录的封装:
/**
* Promise封装开发者服务器登陆(获取登录后的sessionKey)
*/
_serLogin(code) {
return new Promise((resolve, reject) => {
this.request({
url: api.login,
data: {
code: code
},
method: 'post'
})
.then(res => {
wx.setStorageSync('sessionKey', res.data)
console.log('登录成功的回调')
resolve()
})
.catch(err => {
this._show_error('开发者服务器登录失败') //这个是消息提示框,在请求中封装了,这里简单理解错误弹出消息提示。
})
})
}