小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系。
- 前端调用wx.login获取code,再调用后端接口传递code
注意:code是临时的,只有5分钟的使用时间,而且只能使用一次 - 后端用获取的code与微信接口服务换取openid(用户唯一标识)与session_key(可以用于解密私密信息encrydata,现在只能获取头像和昵称),然后生成一个自定义登录状态的token,自定义登录态与openid和session_keysession关联。
注意:不可以把解析出来的openid和session_key直接返回给前端,会造成信息安全问题 - 将token返回给前端
- 前端缓存token
- 用户登录时,登录接口获取到token,再调用其他接口时,拦截器进行拦截,如果token有效,则放行请求;如果token失效(不存在、过期、格式不正确等原因),则无法访问该接口,需要重新登录。
说明:如果觉得token验证太过复杂,也可以退而求其次,采用微信小程序自带的wx.checkSeesion检查下发的session_key是否过期(固定为两天)。
wx.checkSeesion是前端检查,非常方便,但是缺点也很明显:耗时长,通常需要300+ms ,另外前后端传递私密数据时,需要额外考虑数据安全问题(以openid为例,前端每次需要传递openid时,都需要先获取临时code,再传递给后端,后端再用code换取openid,开销极大),因此正式开发时极不建议使用wx.checkSeesion,token验证方式可以较好解决上述问题。
核心代码:
// pages/my/my.js
Page({
/**
* 页面的初始数据
*/
data: {
loginOk: false,
userInfo: null
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
//验证是否登录
this.checklogin()
},
checklogin() {
const token = wx.getStorageSync('token')
const that = this
if (token) {
wx.request({
url: 'http://127.0.0.1:3000/checklogin',
method: 'get',
data:{
token:token
},
success(res) {
that.setData({
loginOk: res.data.is_login,
userInfo: res.data.userInfo
})
}
})
} else {
that.setData({ loginOk: false })
}
},
login() {
const that = this
// 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
wx.getUserProfile({
desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
success(res){
const userInfo = res.userInfo
console.log(userInfo)
// 登录
wx.login({
success(res) {
if (res.code) {
//发起网络请求
wx.request({
url: 'http://127.0.0.1:3000/getSession',
method: 'post',
data: {
code: res.code,
userInfo:userInfo
},
success(res) {
// 将token保存到数据缓存(下次打开小程序无需重新获取token)
wx.setStorageSync('token', res.data.token)
that.setData({
loginOk: true,
userInfo: userInfo
})
}
})
}
}
})
}
})
},
//退出登录
exit() {
wx.showModal({
content: "确定退出吗"
}).then(res => {
if (res.confirm) {
this.setData({
loginOk: false
})
//清空登录的缓存
wx.removeStorageSync('token')
} else if (res.cancel) {
wx.showToast({
title: '取消',
icon:'error'
})
}
})
}
})