这篇文章主要解决以下问题:用户每次登录小程序(包括第一次使用)及点击小程序的每个页面的时候,我们如何判断他当前的登录状态是否过期?如果过期,如何重新获取用户信息并发送至开发者服务器更新用户信息,以及设置新的用户登录状态?
将这个部分单独作为一篇文章有两个原因:
① wx.getUserInfo(OBJECT) 接口调整,废弃了以前直接获取用户信息的方法;
② 上篇文章 授权、登录、session_key、unionId 只梳理了登录流程而没有贴实际的代码,所以这篇文章以代码实现为主。
1. 代码逻辑分析
(1)用户登录态过期时间如何设置?
在上篇文章中也有提到过,用户登录态可以通过前端设置和后端设置两种方式进行控制。这里我们在前端进行控制,即利用wx.checkSession() 接口来判断session_key 是否过期来作为用户登录态是否过期的标志。如果过期了,则跳转到统一的登录页面引导用户点击按钮重新授权登录,重新登录之后session_key 会刷新,相当于在获取用户最新信息的同时重新设定了过期时间。
(2)onShow() 与onLoad()
小程序js 中有onShow 与onLoad 两种事件。两种事件的区别就在于onLoad 每次打开小程序只加载一次,跳转到其他页面再回来的时候这个事件就不会再触发。而onShow 则每次进入页面都会触发,所以我们在进入每个页面检查用户登录态是否过期的代码需要放在onShow 中。
(3)重新登录过程分析
如果用户登录态过期,则需要进行重新登录。登录过程在上篇文章中也有讲过。这里再简单梳理一下:前端引导用户点击按钮触发getUserInfo 获取最新用户信息 -> 前端调用wx.login() 获取code -> 前端将code 发送给后端获取openid 和seesion_key -> 后端写session 并返回对应session 的唯一标志 -> 前端存储这个唯一标志。
2. 代码实例
wx.checkSession({
success: function () {
//session_key 未过期,并且在本生命周期一直有效
return ;
},
fail: function () {
// session_key 已经失效,需要重新执行登录流程
wx.navigateTo({
url: "/pages/authorize/index"
})
}
})
wxml
1、同意当前小程序获取我的微信头像;
2、同意当前小程序获取我的微信昵称等其他信息;
wxss
page{
height: 100%;
}
.container{
background-color: #f5f5f9;
justify-content: initial;
}
.save-btn{
width: 690rpx;
height: 80rpx;
line-height: 80rpx;
text-align: center;
margin-top:30rpx;
border-radius: 6rpx;
box-sizing: border-box;
background-color: #e64340;
color:#fff;
}
js
// pages/authorize/index.js
var app = getApp();
let Domain = app.globalData.domain;
Page({
/**
* 页面的初始数据
*/
data: { },
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) { },
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () { },
/**
* 生命周期函数--监听页面显示
*/
onShow: function () { },
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () { },
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () { },
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () { },
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () { },
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () { },
bindGetUserInfo: function (e) {
// 获得最新的用户信息
if (!e.detail.userInfo){
return;
}
wx.setStorageSync('userInfo', e.detail.userInfo)
this.checkSessionAndLogin();
},
/*
这里使用openid 作为与后端session 连接的标志
检查是否存在openid,即之前是否登录过
如果登录过,检查session_key 是否过期
如果过期了,remove openid 重新执行login 并将用户信息发送到服务器端更新
如果没过期则返回
如果没登录过则执行login 并将用户信息发送到服务器更新
*/
checkSessionAndLogin: function () {
let that = this;
let thisOpenId = wx.getStorageSync('openid');
// 已经进行了登录,检查登录是否过期
if (thisOpenId) {
console.log('have openid')
wx.checkSession({
success: function () {
//session_key 未过期,并且在本生命周期一直有效
wx.navigateBack({});
},
fail: function () {
console.log('but session_key expired');
// session_key 已经失效,需要重新执行登录流程
wx.removeStorageSync('openid');
that.checkSessionAndLogin();
}
})
} else {
// 没有进行登录则先进行登录操作
console.log('do not have openid');
that.loginAndGetOpenid();
}
},
// 执行登录操作并获取用户openId
loginAndGetOpenid: function () {
console.log('do login and get openid');
let that = this;
wx.login({
success: function (res) {
if (res.code) {
wx.request({
url: Domain + '/user/wx_login',
data: {
code: res.code
},
success: function (res) {
res = res.data;
console.log(res)
// 保存openId,并将用户信息发送给后端
if (res.code === 0) {
wx.showModal({
title: 'set openid',
content: res.data,
})
wx.setStorageSync('openid', res.data);
that.sendUserInfoToServer();
} else {
wx.showModal({
title: 'Sorry',
content: '用户登录失败~',
})
}
}
})
}
}
})
},
sendUserInfoToServer: function () {
console.log('now send user info to server');
let userInfo = wx.getStorageSync('userInfo');
let thisOpenId = wx.getStorageSync('openid');
userInfo.openid =thisOpenId;
wx.request({
url: Domain + '/user/updateUser',
method: 'POST',
dataType: 'json',
data: userInfo,
success: function (res) {
res = res.data;
if (res.code === 0) {
wx.navigateBack({});
} else {
wx.showModal({
title: 'Sorry',
content: '同步信息出错~',
})
}
}
})
}
})