主题
token 无感刷新
思路
准备两个 token:
- refresh(长 token):用于刷新 token 使用
- token(短 token):用于业务逻辑使用
在 axios 的相应拦截中统一处理刷新 token 的逻辑,核心如下:
jsimport axios from 'axios' import { getToken, setToken, setRefreshToken } from './token' import { refreshToken, isRefreshRequest } from './auth' const ins = axios.create({ baseURL: 'https://api.example.com', headers: { Authorization: `Bearer ${getToken()}`, }, }) // 拦截器 ins.interceptors.response.use( async function (res) { // 如果服务器返回新的 token,则更新本地 token if (res.headers.authorization) { // 如果服务器返回新的 token,则更新本地 token const token = res.headers.authorization.replace('Bearer ', '') setToken(token) ins.defaults.headers.Authorization = `Bearer ${token}` } // 如果服务器返回新的 refreshtoken,则更新本地 refreshtoken if (res.headers.refreshtoken) { const refreshtoken = res.headers.refreshtoken.replace('Bearer ', '') setRefreshToken(refreshtoken) } // 条件1:如果无权限(可能 token 过期,也可能 refresh 过期) // 条件2:不是 refreshToken 请求 if (res.data.code === 401 && !isRefreshRequest(res.config)) { // 刷新 token const isSuccess = await refreshToken() // 是否成功刷新了 token if (isSuccess) { // 使用新的 token 重新请求 res.config.headers.Authorization = `Bearer ${getToken()}` const res = await ins.request(res.config) return res.data } else { // 无权限 console.log('回到登录页,重新登录') return res.data } } // 正常返回数据 return res.data }, function (error) { return Promise.reject(error) }, )补充 refresh token 的请求逻辑:
jsimport request from './request' import { getRefreshToken } from './token' // 防止重复刷新 token let promise = null /** 刷新 token */ export async function refreshToken() { if (promise) { return promise } promise = new Promise(async (resolve) => { const res = await request.get('/refresh_token', { headers: { Authorization: `Bearer ${getRefreshToken()}`, }, _isRefreshToken: true, }) resolve(res.code === 20000) }) promise.finally(() => { promise = null }) return promise } /** 是否是刷新 token 的请求 */ export async function isRefreshRequest(config) { return !!config._isRefreshToken }
单点登录
什么叫单点登录?
用户在一个应用登录后,可以直接访问其他应用,而不需要再次登录。
例如:用户在应用 A 登录后,可以直接访问应用 B,而不需要再次登录。
常见问题
为什么 token 有效期设置的比较短?
- 安全
- 控制力
