赞
踩
小程序登录开发通常是调用wx.login获取code,然后发送到后台,后台请求微信拿到用户openId,然后根据openId查询用户,有就走登录流程然后返回token,没有则创建用户之后走登录流程然后返回token,也就是都需要返回一个有时效性的token给小程序端,来保持登录状态,并且后续请求都需要token来验证用户。
那么就有一个问题,就是token的时效性,token过期,后台返回认证授权失败,那么怎么做到无感刷新token,让用户即使token过期了自动刷新token呢?经过查询跟实践,我封装了一个请求类。
思路大致是根据后台返回的状态,如果返回的是授权失败,那么就会保存当前请求,调用刷新token的请求,成功之后再次发起之前保存的请求,这样就可以达到用户无感的刷新token。
具体封装类api.js如下,本次代码采用uniapp框架开发,实际项目中每次发起后台请求只需要调用req方法即可做到无感刷新token:
微信小程序自动刷新token,无感刷新token,封装的api工具类https://download.csdn.net/download/weixin_47315082/88041695
- //定义token在Storage中的key值
- var tokenKey = "token";
- //constant.js中定义请求url地址,例如baseUrl:http://192.168.0.5/api
- import constant from './constant.js'
-
- export function logout() {
- //退出时删除token
- uni.removeStorageSync('token')
- }
-
- //定义登录方法,传入wx.login获取到的code
- export function login(data) {
- let header = {};
- header['Content-type'] =
- 'application/json;charset=utf-8';
- return new Promise((resolve, reject) => {
- uni.request({
- //调动后台自定义微信登录方法,获取token
- url: constant.baseUrl + "/wxLogin",
- data: data,
- header: header,
- method: 'POST',
- success(res) {
- try {
- if (res.statusCode === 200 && res.data.code === 200 && res.data.data.token && res.data.data.token !== "false") {
- //获取成功,保存token到Storage中
- uni.setStorageSync(tokenKey, res.data.data.token);
- resolve(res.data)
- } else {
- //获取成功,删除当前Storage中的token
- uni.removeStorageSync('token')
- reject(res)
- }
- } catch (e) {
- console.log("res.data");
- //请求失败
- reject(e)
- }
- },
- fail(err) {
- console.log('request', err)
- //请求失败
- reject(err)
- }
- })
- })
- }
-
- //自定义通用请求类
- export function req(config) {
- let method = config.method || 'GET';
- let url = config.url || "";
- let data = config.data || {};
- let header = config.header || {};
- //关键点:定义一个callback变量,来保存需要刷新token之后再次发起的请求
- let callback = config.callback;
- header['Content-type'] = config.contentType || (method == 'POST_PARAMS' ? 'application/x-www-form-urlencoded' :
- 'application/json;charset=utf-8');
- //获取当前Storage中的token值
- let tokenValue = uni.getStorageSync(tokenKey) || ' ';
- //这里自定义请求,如果请求url中包含"/f/",说明该请求不需要验证token,否则就需要,将token值存入请求头中供后台验证,'Authorization'为后台自定义token的请求头key值
- if (url.indexOf("/f/") < 0) {
- header['Authorization'] = tokenValue;
- }
- return new Promise((resolve, reject) => {
- //发起请求
- uni.request({
- url: constant.baseUrl + url,
- data: data,
- header: header,
- method: method,
- success(res) {
- //如果callback存在,说明是需要再次发起请求,直接调用callback即可
- if (callback) {
- return callback(res.data);
- }
- if (res.statusCode === 401 || res.data.code === 401) {
- //如果返回401,说明当前token认证授权失败,也就是说需要刷新token
- if (tokenValue && tokenValue !== ' ') {
- //删除当前无效token
- uni.removeStorageSync('token');
- }
- //调用重新获取token方法
- getNewToken().then((res) => {
- //获取token成功,将当前请求存入到callback
- config.callback = resolve;
- //获取token成功,重新发起请求
- req(config)
- })
- } else if (res.statusCode === 200) {
- //token有效,返回成功
- resolve(res.data)
- }
- },
- fail(err) {
- console.log('request', err)
- //请求失败
- reject(err)
- }
- })
- })
- }
-
- //重新获取token
- export function getNewToken() {
- return new Promise((resolve, reject) => {
- //调用uni.login获取小程序用户code
- uni.login({
- success(res) {
- //调用login登录
- let loginRes = login({
- code: res.code
- });
- resolve(loginRes);
- },
- fail(err) {
- reject()
- console.error('wx login fail', err);
- }
- });
- })
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。