uni-id-pages解决自动管理token续期,以及token过期客户端自动跳转登录页面的功能

需求描述

在使用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;
	}
}

本期分享就给大家介绍这么多,感谢各位的观看。

相关推荐
阿凤219 天前
后端返回文件二进制流
开发语言·前端·javascript·uniapp
阿凤2110 天前
后端返回数据流的格式
开发语言·前端·javascript·uniapp
绝世唐门三哥12 天前
uniapp系列-uniappp都有哪些生命周期?
vue.js·小程序·uniapp
宠友信息14 天前
社交软件源码哪个渠道好
java·微服务·架构·社交电子·springboot·uniapp
Fate_I_C15 天前
uniappx 鸿蒙运行包制作失败
华为·uni-app·uniapp·harmonyos
咸虾米_1 个月前
使用uniCloud阿里云服务空间的天塌了,云函数计费规则调整了
阿里云·云计算·uniapp·unicloud
蜡台1 个月前
SSE WebSocket Socket.IO 三者使用及区别
websocket·网络协议·uniapp·sse·socket.io·eventsource
路光.1 个月前
uniappVue2升级Vue3内存溢出解决方式
vue·vue3·uniapp
小马_xiaoen1 个月前
常规优化已用尽?小程序体积深层次优化实战!!!
前端·小程序·uniapp