2022年9月7日 06:20 by wst
小程序小程序开发,咋一看有很多限制,其实传统的网页开发基本类似。
下面以我最近遇到的问题,总结下登陆的解决方案。
1.让服务器知道,用户已经登陆且未失效。
2.让前端知道,自己的登陆是否过期。
1. 利用微信的登陆获取登陆后的cookie,并写入缓存。
调用微信登陆--》成功后调用自己的登陆--》登陆后把cookie和有效期写入storage--》每次请求检查是否过期--》如过期再次重复之前的步骤。
2. 利用服务端的session机制,记录是否登陆过期。
判断session失效后返回登陆过期--》前端受到过期后再次调用上面的登陆流程。
1. 启动过程中的鉴权(app.js):
import {
request
} from "./request/index";
onLaunch: function () {
// 判断登录是否失效
var sessionId =wx.getStorageSync('session') || 'nosession'
var expiredTime =wx.getStorageSync('expired') || 0
console.log("session:" + sessionId + ", expired:" + expiredTime)
var now = new Date()
// 未过期,直接进入页面
if (now < expiredTime) {
console.log("登录未失效")
this.globalData.session = sessionId
this.globalData.expired = expiredTime
// 取出缓存中的数据,并赋值给全局变量
var data = wx.getStorageSync('data')
this.globalData.uid = data.uid
this.globalData.role = data.role
} else {
console.log("登录已过期")
this.getLoginInfo() // 过期了,需要重新登录
}
},
2. 登陆过程
getLoginInfo() {
wx.login({ // 登录
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
request({
url: '/user/wx/login',
method: 'POST',
data: {
code: res.code
},
}).then(
res => {
console.log("logined data:", res)
this.globalData.uid = res.data.uid
this.globalData.role = res.data.role
wx.setStorageSync('data', res.data)
}
).catch(
(errMsg)=>{console.log("error ...", errMsg);}
)
},
fail: res=>{
console.log("login error", res)
}
})
},
3. 封装微信的原始请求(request/index.js)
import {
BASE_URL
} from '../config'
// 同时发送异步代码的次数
let ajaxTimes = 0;
export const request = (params) => {
// 判断 url中是否带有 /my/ 请求的是私有的路径 带上header token
let header = {
...params.header
};
// 拼接header 带上token
header["session"] = wx.getStorageSync('session') || 'nosession';
ajaxTimes++;
// 显示加载中 效果
wx.showLoading({
title: "加载中...",
mask: true
});
// 封装原始请求
return new Promise((resolve, reject) => {
wx.request({
...params,
header: header,
url: BASE_URL + params.url,
timeout: 30000,
success: (result) => {
resolve(result.data);
if (params.url.includes("/user/wx/login")) {
// 把登录返回的session写入缓存
console.log("登录cookie已写入缓存")
wx.setStorageSync('session', result.header.session)
wx.setStorageSync('expired', result.header.expired)
}
if (result.data.code === 6) {
console.log("url:", params.url)
// 处理登录过期的情况
login()
}
},
fail: (err) => {
console.log("request error:", err)
reject(err);
},
complete: () => {
ajaxTimes--;
if (ajaxTimes === 0) {
// 关闭正在等待的图标
wx.hideLoading();
}
}
});
})
}
export const login = () => {
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
request({
url: '/user/wx/login',
method: 'POST',
data: {
code: res.code
},
}).then(res => {
var app = getApp()
console.log("logined[single] data:", res.data)
wx.setStorageSync('data', res.data)
app.globalData.uid = res.data.uid
app.globalData.role = res.data.role
wx.reLaunch({
url: '/pages/welcome/welcome',
})
})
}
})
}
关于具体实现,如有问题可评论,进一步讨论。