
需求描述
在使用uniapp+unicloud开发项目的时候,少不了使用uni-id-pages来管理用户体系,你肯定也观察过一些网站,如果登陆一次之后,不间断的访问网站的话,就会发现只需要登陆过一次以后,未来都不需要再登陆,但是隔很长时间不访问的话,再次打开网站就会让再次登陆了,上面这个描述涉及到的就是token的自动续期。
token是什么?
token是服务器颁发给客户端的一个令牌。
用户在客户端登录时,云端通过登录接口对用户的用户名+密码,或者手机号+验证码进行校验,校验通过后服务器会给客户端下发一个token(就是根据tokenSecret生成的一串加密字符串),并同时给出有效期。
客户端把这个token保存在storage中,然后每次联网请求服务器时,都带上这个token。服务器解密这个token,通过这个token认定客户端的身份。
这样就避免了客户端每次请求服务器,都需要再传输一次用户名和密码。
这是业内通行的设计。
uni-id-pages这个插件也是可以自动续期的,而且比传统的token校验续期更方便,因为uniapp框架已经把这些工作都做好了,但是DCloud官方文档写的太模糊导致新手根本不知道怎么操作,下面就把我写好的实际项目代码为大家进行展示,作为参考学习。
一.校验token
如果客户端端调用该云对象的时候,需要客户端保持登录状态的话,首先要判断客户端是否传递了token,这样会出现两种情况:
情况一:不存在token
直接抛出错误,让客户端跳转到设置好的登陆页面,核心实现逻辑如下代码所示:
javascript
//index.obj.js
module.exports = {
_before: async function () {
let token = this.getUniIdToken();
if(!token) throw { errCode: 'uni-id-check-token-failed', errMsg: 'token校验未通过,需登录' };
},
xxx(){
//你自己的业务函数
},
_after:function(error, rslt){
if (error) {
return error;
}
return rslt;
}
}
关键点:
1.在_before中通过throw抛出错误,抛出的对象一定要按照unicloud返回的格式,errCode必须设置正确的错误码(云端错误码),errMsg可以自定定义展示的文本。
2.要在_after中return返回错误信息,这一步必须做,不然客户端只会接收到云对象返回的错误,但是不会自动跳转到登陆页面。
情况二:存在token需要校验token的正确性
情况一决定了必须传入token,如果不传入token就直接让客户端进入到登录页面,但是有时候客户端传入了token但是存在token过期或者token无效的情况,这个必须进行校验之后才能进行后续的业务逻辑,核心实现逻辑如下:
javascript
//index.obj.js
const uniID = require('uni-id-common'); //引入uni-id公共模块
module.exports = {
_before: async function () {
let clientInfo = this.getClientInfo();
let token = this.getUniIdToken();
if(!token){throw { errCode: 'uni-id-check-token-failed', errMsg: 'token校验未通过,需登录' };
}else{
// 创建uni-id实例
let uniIDIns = uniID.createInstance({
clientInfo
});
// 校验token并返回值
this.payload = await uniIDIns.checkToken(token);
if (this.payload.code != 0) {
throw this.payload;
}
}
},
xxx(){
//你自己的业务函数
},
_after:function(error, rslt){
if (error) {
return error;
}
return rslt;
}
}
关键点:
1.createInstance创建uni-id实例,传入客户端传入的信息clientInfo。
2.给uni-id实例调用checkToken()token校验接口。
3.将校验返回值赋值给this.payload,方便后续其他方法调用,因为相应参数里面包含很多的有用信息,如:errCode错误码、uid用户唯一ID、token只有快过期时才返回新token(下面有详细说明)、tokenExpired新token的过期时间同样是token快过期才会有值、role角色组、permission权限组。
4.errCode只有等于0的时候才代码token校验通过,不等于0的话一律抛出throw this.payload 校验返回的相应值。
小结
将情况二完整代码分别放到_before和_after中,这样肯定是可以实现token无效或者token过期,客户端自动跳转到登陆页面,客户端不需要做任何代码的变动,还是比较方便的吧。
但是目前是可以校验token的,但是还没有实现token续期,下面是token续期的实现。
二、token自动续期
1.设置token有效期和刷新阈值
要想实现token自动续期,首先你需要在云端配置config.json。
uni-id的云端配置文件在uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json中。
下面以web配置为例,如果你要做微信小程序或app都是同样配置这两个参数,tokenExpiresIn是token有效期,tokenExpiresThreshold是token刷新阈值,值的单位为秒。
javascript
"web": {
"tokenExpiresIn": 86400,
"tokenExpiresThreshold": 28800,
}
举个例子,开发者配置的token有效期(tokenExpiresIn)为1天(86400秒),token刷新阈值(tokenExpiresThreshold)为8小时(28800秒 )。用户在0点0分0秒获取了token,如果用户在16点后(token有效期已小于8小时)调用接口时执行了checkToken方法则会返回新token。
2.给客户端返回newToken
可以在任意函数的参数中传入该newToken属性,传入的值就是在使用checkToken()接口返回的this.payload。
- 可以在云对象的函数中返回,如:
javascript
banner(){
return {errCode:0,errMsg:"操作成功",data:[],newToken:this.payload}
}
- 通常放到_after中统一处理,先判断token校验返回的值里面包含token和tokenExpired吗,只有临近过期的时候才有这两个值,否则这两个值是空,所以临期的时候才给响应参数返回newToken值,如:
javascript
_after: function(error, rslt){
if (error) {
return error;
}
if (this.payload.token && this.payload.tokenExpired) rslt.newToken = this.payload;
return rslt;
}
总结
这样就实现了uni-id-pages插件基于uni-id用户体系,进行token的校验和自动续期,如果你有更好的方法可以给我评论留言,帮助到你不要忘了点赞收藏哦,完整代码如下所示:
javascript
//index.obj.js
const uniID = require('uni-id-common'); //引入uni-id公共模块
module.exports = {
_before: async function () {
let clientInfo = this.getClientInfo();
let token = this.getUniIdToken();
if(!token){throw { errCode: 'uni-id-check-token-failed', errMsg: 'token校验未通过,需登录' };
}else{
// 创建uni-id实例
let uniIDIns = uniID.createInstance({
clientInfo
});
// 校验token并返回值
this.payload = await uniIDIns.checkToken(token);
if (this.payload.code != 0) {
throw this.payload;
}
}
},
xxx(){
//你自己的业务函数
},
_after:function(error, rslt){
if (error) {
return error;
}
if (this.payload?.token && this.payload?.tokenExpired) rslt.newToken = this.payload;
return rslt;
}
}
本期分享就给大家介绍这么多,感谢各位的观看。