温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

无感知刷新Token是什么

发布时间:2023-04-04 11:18:17 来源:亿速云 阅读:107 作者:iii 栏目:开发技术

这篇文章主要介绍了无感知刷新Token是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇无感知刷新Token是什么文章都会有所收获,下面我们一起来看看吧。

    Token认证的原理

    在Web应用中,常见的Token认证方式有基于Cookie和基于Token的认证。基于Cookie的认证方式是将认证信息保存在Cookie中,每次请求时将Cookie发送给服务器进行认证;而基于Token的认证方式是将认证信息保存在Token中,每次请求时将Token发送给服务器进行认证。

    在基于Token的认证方式中,客户端将认证信息保存在Token中,而不是保存在Cookie中。在认证成功后,服务器将生成一个Access Token和一个Refresh Token,并将它们返回给客户端。Access Token用于访问受保护的API,Refresh Token用于获取新的Access Token。

    什么是无感知刷新Token

    无感知刷新Token是指,在Token过期之前,系统自动使用Refresh Token获取新的Access Token,从而实现Token的无感知刷新,用户可以无缝继续使用应用。

    在实现无感知刷新Token的过程中,需要考虑以下几个方面:

    • 如何判断Token是否过期?

    • 如何在Token过期时自动使用Refresh Token获取新的Access Token?

    • 如何处理Refresh Token的安全问题?

    下面将介绍如何实现无感知刷新Token的具体步骤。

    实现步骤

    步骤一:获取Access Token和Refresh Token

    在认证成功后,需要将Access Token和Refresh Token发送给客户端。Access Token用于访问受保护的API,Refresh Token用于获取新的Access Token。可以使用JWT(JSON Web Token)或OAuth3(开放授权)等方式实现认证。

    在JWT中,可以使用如下代码生成Access Token和Refresh Token:

    const accessToken = jwt.sign({userId: '123'}, 'ACCESS_TOKEN_SECRET', {expiresIn: '15m'});
    const refreshToken = jwt.sign({userId: '123'}, 'REFRESH_TOKEN_SECRET', {expiresIn: '7d'});

    步骤二:在请求中携带Access Token

    在每个需要认证的API请求中,需要在请求头中携带Access Token,如下所示:

    GET /api/user HTTP/1.1
    Host: example.com
    Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

    在前端中,可以使用Axios等库设置请求头:

    axios.defaults.headers.common['Authorization'] = `Bearer ${accessToken}`;

    步骤三:拦截401 Unauthorized响应

    在服务器返回401 Unauthorized响应时,说明Access Token已经过期,需要使用Refresh Token获取新的Access Token。可以使用Axios拦截器或Fetch API的中间件实现拦截。

    在Axios中,可以使用如下代码实现拦截器:

    axios.interceptors.response.use(response => {
      return response;
    }, error => {
      const originalRequest = error.config;
      if (error.response.status === 401 && !originalRequest._retry) {
        originalRequest._retry = true; //防止无限调用
        return axios.post('/api/refresh_token', {refreshToken})
          .then(response => {
            const { access_token, refresh_token } = response.data;
            localStorage.setItem('access_token', access_token);
            localStorage.setItem('refresh_token', refresh_token);
            axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}`;
            originalRequest.headers.Authorization = `Bearer ${access_token}`;
            return axios(originalRequest);
          });
      }
      return Promise.reject(error);
    });

    在Fetch中,可以使用如下代码实现中间件:

    function authMiddleware(request) {
      const access_token = localStorage.getItem('access_token');
      if (access_token) {
        request.headers.set('Authorization', `Bearer ${access_token}`);
      }
      return request;
    }
    function tokenRefreshMiddleware(response) {
      if (response.status === 401) {
        const refreshToken = localStorage.getItem('refresh_token');
        return fetch('/api/refresh_token', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({ refreshToken })
        }).then(response => {
          if (response.ok) {
            return response.json();
          }
          throw new Error('Refresh Token failed');
        }).then(data => {
          localStorage.setItem('access_token', data.access_token);
          localStorage.setItem('refresh_token', data.refresh_token);
          return Promise.resolve('refreshed');
        }).catch(error => {
          localStorage.removeItem('access_token');
          localStorage.removeItem('refresh_token');
          return Promise.reject(error);
        });
      }
      return Promise.resolve('ok');
    }
    fetch('/api/user', {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json'
      },
      middleware: [authMiddleware, tokenRefreshMiddleware]
    }).then(response => {
      console.log(response);
    }).catch(error => {
      console.error(error);
    });

    在上述代码中,使用Axios或Fetch拦截器拦截401 Unauthorized响应,如果发现Access Token已经过期,则发送Refresh Token请求获取新的Access Token,并将新的Access Token设置到请求头中,重新发送请求。

    步骤四:服务器处理Refresh Token请求

    在服务器端,需要编写API处理Refresh Token请求,生成新的Access Token,并返回给客户端。

    在JWT中,可以使用如下代码生成新的Access Token:

    const accessToken = jwt.sign({userId: '123'}, 'ACCESS_TOKEN_SECRET', {expiresIn: '15m'});

    在刷新Token时,需要验证Refresh Token的合法性,可以使用如下代码验证Refresh Token:

    try {
      const payload = jwt.verify(refreshToken, 'REFRESH_TOKEN_SECRET');
      const accessToken = jwt.sign({userId: payload.userId}, 'ACCESS_TOKEN_SECRET', {expiresIn: '15m'});
      const refreshToken = jwt.sign({userId: payload.userId}, 'REFRESH_TOKEN_SECRET', {expiresIn: '7d'});
      res.json({access_token: accessToken, refresh_token: refreshToken});
    } catch (err) {
      res.sendStatus(401);
    }

    在上述代码中,使用JWT的verify方法验证Refresh Token的合法性,如果验证成功,则生成新的Access Token和Refresh Token,并返回给客户端。

    步骤五:设置定时刷新Token

    为了避免Access Token过期时间太长,可以设置定时刷新Token的功能。可以使用定时器或Web Workers等方式实现定时刷新Token。在每次刷新Token时,需要重新获取新的Access Token和Refresh Token,并保存到客户端。

    function refreshToken() {
      const refreshToken = localStorage.getItem('refresh_token');
      axios.post('/api/refresh_token', {refreshToken})
        .then(response => {
          const { access_token, refresh_token } = response.data;
          localStorage.setItem('access_token', access_token);
          localStorage.setItem('refresh_token', refresh_token);
          axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}`;
        })
        .catch(error => {
          console.error(error);
        });
    }
    setInterval(refreshToken, 14 * 60 * 1000); // 每14分钟刷新Token

    在上述代码中,使用定时器每14分钟刷新Token。在刷新Token成功后,将新的Access Token和Refresh Token保存到客户端,并将新的Access Token设置到请求头中。

    安全性考虑

    在实现无感知刷新Token的过程中,需要考虑到Refresh Token的安全性问题。因为Refresh Token具有长期的有效期限,一旦Refresh Token被泄露,攻击者就可以使用Refresh Token获取新的Access Token,从而绕过认证机制,访问受保护的API。

    为了增加Refresh Token的安全性,可以考虑以下几种措施:

    • 将Refresh Token保存在HttpOnly Cookie中,可以避免在客户端被JavaScript获取;

    • 对Refresh Token进行加密或签名,可以增加其安全性。

    • 将Refresh Token保存在后端,前端通过接口和后端交互,实现刷新Access Token。

    关于“无感知刷新Token是什么”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“无感知刷新Token是什么”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注亿速云行业资讯频道。

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI