微信小程序静默登录

1.背景

    最近开发了一个微信小程序,但是后端这里想简化处理,没有严格给出token的自动刷新接口,同时对于token的有效期时间也没有配置。前端这里觉得既然要简化就简化处理吧,于是就利用vuex缓存,后来在实际使用的过程中发现了一些问题,这里总结一下。

2.问题一:token的刷新时机?

    最开始设置的是不刷新模式,用户首次进入,判断是否登录(isLogin),这里isLogin与token是否存在直接绑定,如果没有token意味着isLogin为false,这时在调用后端接口的时候借助request拦截器来拦截token失效状态码(B0003),如果成功拦截到这个token失效码,则主动帮助用户跳转到登录模块(即这里的toLogin()):

function baseRequest(url, method, data, {
	noAuth = false
}) {
	let Url = HTTP_REQUEST_URL,
		header = HEADER;
	if (!noAuth) {
		if (!store.state.app.token && !checkLogin()) {
			toLogin();
			return Promise.reject({
				msg: i18n.t(`未登录`)
			});
		}
	}
	if (store.state.app.token) header[TOKENNAME] = store.state.app.token;

	return new Promise((resolve, reject) => {
		uni.request({
			url: Url + "/" + url,
			method: method || 'GET',
			header: header,
			data: data || {},
			success: (res) => {
				if (res.data.code === "00000") {
					resolve(res.data.data);
				} else if (res.data.code === "B0003") {
					reject({
						msg: i18n.t(`token失效,请重新登录~`)
					});
					setTimeout(() => {
						toLogin();
					}, 1500);
				} else {
					reject({
						msg: i18n.t(res.data.msg || `系统错误~`)
					});
				}
			},
			fail: (msg) => {
				reject({
					msg: i18n.t(msg || "系统错误~")
				});
			}
		})
	});
}

    这样存在什么问题呢?乍一看好像没有问题,但是站在用户的角度,用户可能前几天使用了小程序,结果今天使用的时候进去发现token失效,请重新登录~,给用户的感觉不是很友好,于是决定采用一层静默登录。实现方式是,用户进入小程序首页,在生命周期函数Onload里面调用登录接口,这样能够保证信息同步,但是实际使用发现,如果浏览的小程序页面较多的话,那么onLoad不止调用一次,相当于给了一个token频繁刷新,这样显然也不太合理。
    如果是使用缓存呢,首次进入之后刷token同时在缓存中记录这个token已经被刷新过(isTokenRefresh),可以是可以,但是还存在一个小问题,如果token失效了,需要让用户跳转登录模块,走一遍登录授权,这时将isTokenRefresh设置为false,那么登录完成之后,回到首页会导致token因为登录流程刷了一次,回到首页又刷了一次。那可以不修改isTokenRefresh不,这样是不行的,那这样在之后的登陆中变成了单次可用了。要是不走登录流程呢,token失效了直接isTokenRefresh设置为false,回到首页不行吗,这样也不太好,因为可能用户主动退出登录,让用户重新走登录流程更合理。因此,缓存方案不是特别好。
    于是问了一下豆包,豆包这里提到了在原型中挂全局变量,这种方案是可行的:
在这里插入图片描述
    还有一种类似的方案,借助vuex不能够在应用中持续缓存的特点,首次初始化isTokenRefresh为false,然后在vuex中调用UPDATE_TOKEN标记token被刷新过,这样也能够很好的解决首次进入单次刷新token问题了。

//pages/index/index
onLoad() {
		const isTokenRefresh = this.$store.state.app.isTokenRefresh;
		if (!isTokenRefresh) {
			Routine.getCode().then(code => {
				authType({ code }).then(data => {
					const {userAvatar, userNick,token} = data;
					this.$store.commit('UPDATE_USERINFO', { nickname: userNick, avatar: userAvatar});
					this.$store.commit('LOGIN', {
						token: token
					});
					this.$store.commit('UPDATE_TOKEN');
					this.initData();
				});
			});
		} else {
			this.initData();
		}
	},
//vuex
const state = {
	token: uni.getStorageSync('LOGIN_STATUS') || false,
	userInfo: uni.getStorageSync('USER_INFO') ? JSON.parse(uni.getStorageSync('USER_INFO')) : {},
	homeActive: false,
	isTokenRefresh: false,
};

const mutations = {
	UPDATE_TOKEN(state) {
		state.isTokenRefresh = true;
	},
}

3.如果后端可以无限配合,token该怎么维护呢?

    下面给出最理想的方案,后端能够按照我们前端所想无限配合,那这块该如何开发呢?那这里就需要准备两个接口了,一个是token是否有效isTokenValid,还有一个token刷新接口是refreshToken,用户进入首页首先调用isTokenValid检测token是否有效,如果失效直接调用refreshToken刷一次,否则不需要刷新,这样能够保证token的使用时间最大化;如果token失效了,则主动调用一次refreshToken刷新,对于用户主动退出登录状态的情况,可以设置一个manualLogout字段来配合,在刷refreshToken刷新之前判断一下是否是主动退出,如果主动退出那么重置manualLogout为false并走登录流程。类似的还可以后端给一个token的失效时间,但是这样在账号token被顶这个失效时间会异常,最好的还是后端去判断是否有效。最后,很感谢您能够读到这里,希望对您有所帮助,关注点赞分享更多前端知识。

### 关于微信小程序中的静默登录微信小程序环境中,静默登录是一种无需用户额外操作即可完成身份验证的方式。当涉及到具体实现时,主要依赖于`uni.login()`函数来获取临时的code值[^3]。 #### 获取Code并交换Session Key 为了实现静默登录功能,在前端部分可以通过调用`uni.login({})`获得一个临时性的验证码(即code),此过程不会打扰用户体验,因为它是自动执行的。得到code之后,服务端需利用该code连同其他必要参数如appid、AppSecret以及固定的字符串"authorization_code"作为grant_type向指定URL发送请求: ```javascript // 前端代码片段用于发起静默登录流程 uni.login({ success(res) { if (res.code) { console.log('Login succeeded, code:', res.code); // 将code传递给后台处理... } else { console.error('Failed to get login information'); } }, }); ``` 随后,后端应构建HTTP GET请求至`https://api.weixin.qq.com/sns/jscode2session?`接口,并附带上述提到的各项参数以换取session_key及openId等信息。 #### 后台逻辑处理 一旦从前端接收到code,服务器侧就需要负责将其转换成有效的会话凭证(session_key),这一步骤至关重要,因为它不仅能够帮助开发者识别特定的小程序实例,而且对于后续访问开放平台所提供的API资源不可或缺[^1]。 需要注意的是,尽管静默授权可以简化初次接入环节,但它仅能提供有限的信息量——特别是用户的唯一标识符(openid)[^2]。因此,如果应用需求涉及更详细的个人资料,则可能还需要引导用户进行显式的权限授予动作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jerry说前后端

请作者喝杯冰阔落~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值