uni-app 无痛刷新 token 方法

Posted 浚琦的代码世界

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uni-app 无痛刷新 token 方法相关的知识,希望对你有一定的参考价值。

为了给用户一个流畅的体验, token 过期后需要重新请求新的 token 替换过期的 token 

前端在请求接口时,和后端定义好了,如果状态码为 401 ,则表明 token 过期,需要前端请求新的 token

 流程思路参考: https://www.jianshu.com/p/58f05bf13b7d

大概流程如下:

1.用户登录之后,后端会返回两个 token ,分别为 accessToken 和 refreshToken 存储到 Storage

平时请求数据时,请求头使用 accessToken 来发送接口

2.当返回401 token 过期后, 我们通过接口向后端获取新的 token ,请求参数为 refreshToken

3.我们拿到新的 accessToken 和 refreshToken 之后, 替换掉之前的 Storage 中存储的 token

4.同时还要将我们报 401 的哪个接口 ,使用新的 accessToken ,重新请求一次, 拿到数据,实现无痛刷新 token

5.如果后端返回的新的 token 也无法使用,表明需要重新登录,跳到登录页(这一步可以灵活使用,我个人用的是一个路由插件配合使用的: https://ext.dcloud.net.cn/plugin?id=578)

 

配合uni-app的插件进行使用和实现:

到uni-app的插件市场下载 封装的request网络请求 ,按照文档配置到自己的项目上

地址: https://ext.dcloud.net.cn/plugin?id=159

配置好后修改 vmeitime-http 文件夹下的  index.js 文件

 

 

 

 再修改 vmeitime-http 文件夹下的  interface.js 文件,将401状态暴漏出来

 

如果看到这里还是看不明白,那么请看我的源码,请注意我使用了两个插件,观众们酌情理解,仔细消化,配合到自己的项目中思考...

源码点下面的折叠小加号 ⬇ (老有人问我要源码,源码在下面)

 

import http from \'./interface\'
import config from \'./config\'

// request.js
import Vue from \'vue\'
import Router  from \'@/router\'

//...其它逻辑代码

export const execute = (name, data = {}) => {

    //设置请求前拦截器
    http.interceptor.request = (config) => {
        let token = uni.getStorageSync(\'accessToken\')
        delete config.header[\'x-access-token\']
        if (token) {
            config.header[\'x-access-token\'] = token
        }
    }
    //设置请求结束后拦截器
    http.interceptor.response = async (response) => {
        const statusCode = response.statusCode;
        if (statusCode === 401) {
            response = await doRequest(response)
        }
        if (statusCode === 402) {
            uni.removeStorageSync(\'accessToken\');
            uni.removeStorageSync(\'refreshToken\');
            uni.removeStorageSync(\'realname\');
            let jump = uni.getStorageSync(\'jump\')
            if (!jump) {
                setTimeout(() => {
                    uni.showModal({
                        title: \'提示\',
                        content: \'您的账号在其它地点登录!\',
                        showCancel: false,
                        success: function(res) {
                            if (res.confirm) {
                                Router.push({
                                    name: \'login\',
                                    params: {
                                        \'RouterName\': \'home\'
                                    }
                                })
                            }
                        },
                    })
                });
                uni.setStorageSync(\'jump\', \'true\')
            }
        }
        if (statusCode == 403) {
            let jump = uni.getStorageSync(\'jump\')
            if (!jump) {
                setTimeout(() => {
                    Router.replace({
                        name: \'login\',
                        params: {
                            \'RouterName\': \'home\'
                        }
                    })
                },500)
                uni.setStorageSync(\'jump\', \'true\')
            }
        }
        // 统一处理错误请求
        const code = response.data.code;
        const message = response.data.message;
        if (response.statusCode == 200 && code !== 0 && code != -1 && code) {
            uni.showToast({
                title: message,
                icon: "none",
                duration: 2000
            });
        }
        return response;
    }
    return http.request({
        name: name,
        baseUrl: config.base,
        url: config.interface[name].path,
        method: config.interface[name].method ? config.interface[name].method : \'GET\',
        dataType: \'json\',
        data,
    })
}

export default {
    execute
}
    // 刷新 token 方法
    async function doRequest(response) {
        const res = await execute(\'refresh\', {refreshToken: uni.getStorageSync(\'refreshToken\')})
        const {
            code,
            data
        } = res.data
        if (code == 0) {
            uni.setStorageSync(\'accessToken\', data.accessToken)
            uni.setStorageSync(\'refreshToken\', data.refreshToken)
            let config = response.config
            config.header[\'x-access-token\'] = data.accessToken
            const resold = await execute(config.name,{ ...config.data
            })
            return resold
        } else {
            uni.removeStorageSync(\'accessToken\');
            uni.removeStorageSync(\'refreshToken\');
            uni.showToast({
                title: \'登陆过期请重新登陆!\',
                icon: "none",
                success() {
                    Router.push({
                        name: \'login\',
                        params: {
                            \'RouterName\': \'home\'
                        }
                    })
                }
            });
        }
    }
View Code

 

以上是关于uni-app 无痛刷新 token 方法的主要内容,如果未能解决你的问题,请参考以下文章

配置项目请求地址和axios以及实现token过期无痛刷新

uni-app保存数据到本地

uni-app 小程序返回上一页并刷新数据的方法

无感刷新token

自动刷新android片段,直到满足条件

React-umi-request动态刷新Token功能实现及node.js 代码逻辑