refresh无感刷新

该博客主要探讨了在API请求中遇到401未授权错误时如何处理JWT Token的失效问题。当Token失效时,检查是否存在refresh_token,如果有,则通过PUT请求使用refresh_token获取新Token,并更新本地存储及请求配置,从而实现无感知续签,若refresh_token也失效,则引导用户重新登录。

处理token失效问题

token

refresh_token

request.interceptors.response.use(
  response => {
    // 成功的
    return response
  },
  async error => {
    // 对响应错误做点什么
 
    //1 token 问题
    // 失效 ?  没有token ?
    if (error.response.status === 401) {
      //2. 判断 refresh_token 有没有
      let user = store.state.user
      // 2.1 没有 refresh_token
      if (!user.refresh_token) {
        // 提示
        Toast.fail(error.response.data.message)
        // 跳转
        router.push('/login')
        return
      }
 
      // 2.2 有 refresh_token => 换取 新的token
      try {
        let res = await axios({
          method: 'put',
          url: 'http://toutiao.itheima.net/v1_0/authorizations',
          headers: {
            Authorization: `Bearer ${user.refresh_token}`,
          },
        })
 
        console.log(res.data)
 
        // 3 替换本地的token
        store.commit('setUser', {
          token: res.data.data.token,
          refresh_token: user.refresh_token,
        })
 
        //4. 把之前 失效的token `请求` ==> 改为用最新的token `请求` 替代 => 继续请求
        return request(error.config)
      } catch (error) {
        // refresh_token  有值 , 但是过期了, 请求失败
        router.push('/login')
      }
    }
 
    return Promise.reject(error)
  }
)

### 实现 Refresh Token 无感刷新的最佳实践 #### 使用 Vue 和 Express 的实现方案 在前端部分,Vue 应用程序可以通过拦截器来捕获 HTTP 请求中的错误响应并尝试刷新访问令牌。当检测到 `401 Unauthorized` 响应时,应用程序会触发刷新过程。 ```javascript import axios from 'axios'; const instance = axios.create({ baseURL: process.env.VUE_APP_API_URL, }); let isRefreshing = false; let failedQueue = []; // Add a request interceptor instance.interceptors.request.use( config => { const accessToken = localStorage.getItem('access_token'); if (accessToken) { config.headers.Authorization = `Bearer ${accessToken}`; } return config; }, error => Promise.reject(error) ); // Add a response interceptor instance.interceptors.response.use( response => response, async error => { const originalRequest = error.config; if (error.response.status === 401 && !originalRequest._retry) { if (isRefreshing) { return new Promise((resolve, reject) => { failedQueue.push({ resolve, reject }); }) .then(token => { originalRequest.headers['Authorization'] = 'Bearer ' + token; return instance(originalRequest); }) .catch(err => Promise.reject(err)); } originalRequest._retry = true; isRefreshing = true; try { const { data } = await axios.post('/auth/refresh', {}, { headers: { Authorization: `Bearer ${localStorage.getItem('refresh_token')}` } }); if (data.access_token) { localStorage.setItem('access_token', data.access_token); originalRequest.headers['Authorization'] = 'Bearer ' + data.access_token; while(failedQueue.length){ let queueItem = failedQueue.shift(); queueItem.resolve(data.access_token); } isRefreshing = false; return instance(originalRequest); } } catch (_error) { console.error(_error); isRefreshing = false; while(failedQueue.length){ let queueItem = failedQueue.shift(); queueItem.reject(_error); } // Redirect to login or handle session expiration here. window.location.href = '/login'; } } return Promise.reject(error); } ); export default instance; ``` 这段代码展示了如何设置 Axios 拦截器以处理未授权的 API 调用,并通过发送带有刷新令牌的新请求来获得新的访问令牌[^1]。 对于后端而言,在 Node.js 中使用 Express 可以为客户端提供一个专门用于交换新访问令牌的服务接口: ```javascript app.post('/auth/refresh', verifyRefreshTokenMiddleware, async(req, res) => { try{ const userPayload = req.user; // Assume this comes from middleware that verifies the refresh token const payload = { id: userPayload.id, email: userPayload.email }; const options = { expiresIn: "1h" }; const accessToken = jwt.sign(payload, SECRET_KEY, options); return res.json({ access_token : accessToken}); }catch(e){ next(new Error("Failed to generate access token")); } }) ``` 此服务接收来自客户端的 POST 请求以及附带的有效刷新令牌作为认证头的一部分。如果验证成功,则签发一个新的短期有效的 JWT 访问令牌给调用者[^3]。 这种设计不仅提高了用户体验,还增强了系统的安全性和简化了开发工作流[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值