使用刷新令牌来获取新的访问令牌反应和节点 js

Posted

技术标签:

【中文标题】使用刷新令牌来获取新的访问令牌反应和节点 js【英文标题】:using refresh token to get new access token react and node js 【发布时间】:2021-09-04 07:31:20 【问题描述】:

我已经为用户身份验证构建了一个 JWT API。我想用它来反应。 我的应用有这些路线:

Node js API 路由:

http://localhost:8080/api/auth/signin -> 这个路由接受来自 react 的用户名和密码,并发送回一个访问令牌进行响应,它将把它保存在 localstorage 中(我打算改用内存)和包含启用 httpOnly 的刷新令牌的 cookie。

http://localhost:8080/api/auth/signup -> 此路由将根据用户输入将新用户添加到数据库(与身份验证过程无关)

http://localhost:8080/api/auth/refreshtoken -> 此路由将根据保存在 cookie 中的客户端发送的刷新令牌返回一个新的访问令牌。然后客户端将用过期的访问令牌替换它。

http://localhost:8080/api/test/user -> 这将检查用户是否使用来自客户端的访问令牌登录并将用户数据发回

React 客户端路由:

http://localhost:3000/login -> 发送用户登录信息的路由

http://localhost:3000/register -> 创建新用户的路由

http://localhost:3000/user -> 需要用户登录才能查看数据的受保护路由。

当我登录到我的网站时,我可以在访问令牌到期前 20 秒内看到用户路由内的数据。当访问令牌过期并且我发出新请求时,服务器将响应 401 未经授权的代码。所以这样我可以确保访问令牌已过期,我需要使用刷新令牌。我是这样做的:

const API_URL = "http://localhost:8080/api/test/";

const getUserBoard = () => 
  return axios.get(API_URL + "user",  headers: authHeader() )
            .catch((error) => 
              if(error.response.status === 401) 
                // if error response status was 401 then request a new token
                authService.refreshToken();
                window.location.reload();
              else if(error.response.status === 403) 
                authService.logout();
                window.location.href = "/login";
              
            );
;

使用刷新令牌获取新访问令牌的代码:

const refreshToken = () => 
  axios(
    url: API_URL + "refreshtoken",
    method: "POST",
    withCredentials: true
  )
    .then((response) => 
      if(response.data.accessToken) 
        const user = JSON.parse(localStorage.getItem("user"));
        user.accessToken = response.data.accessToken;
        localStorage.setItem("user", JSON.stringify(user));
      
    )
    .catch((error) => 
      console.log("server: " + JSON.stringify(error.response));
    )

设置标头以使用访问令牌从服务器接收数据的代码:

export default function authHeader() 
    const user = JSON.parse(localStorage.getItem('user'));
  
    if (user && user.accessToken) 
      // for Node.js Express back-end
      return  'x-access-token': user.accessToken ;
     else 
      return ;
    
  

在 401 错误上获取新访问令牌的第一部分效果很好,但我的刷新令牌也在 40 秒后过期。 如果我发送过期的刷新令牌,它不会返回新的访问令牌。因此,我将再次收到 401 错误,这将再次导致 403 错误,在这里我将陷入无限的重新加载循环。

有什么想法吗?如何控制令牌到期?

【问题讨论】:

【参考方案1】:

您是在您的 node.js 应用程序中发行令牌,对吧?因此,您应该在此处调整令牌的到期时间。颁发令牌的代码应该有一个设置过期时间的选项。

请记住,一旦刷新令牌过期,您应该再次登录。您可以实现称为滚动刷新令牌的东西。因此,每当您调用 /api/auth/refreshtoken 端点时,您还可以发出一个新的刷新令牌,具有新的到期时间并将其返回到 cookie 中。

【讨论】:

我的问题在于响应。当服务器以 403 响应响应时,它还会抛出 401 响应,这将导致我的代码中出现无限循环。刷新令牌是一个 httpOnly cookie。那么如何在一定时间后注销用户?使用 setTimeOut 1 天?! 查看您的代码 - 如果您收到 403 响应,那么您正在注销用户。这似乎没问题。为什么会陷入死循环? 因为正如我所说的访问令牌无效,那么响应是 401。如果响应是 401,它将刷新访问令牌。但是刷新令牌已过期,因此会引发 403 错误并将错误发送到 refreshtoken 函数。然后页面将刷新错误 401 并假设有一个新的访问令牌。再试一次,但那里没有任何有效的令牌。所以它将再次收到 401 错误,页面将刷新等等... 我刚刚修好了。我将 403 错误检查移至 refreshtoken 功能。现在它工作得很好。谢谢。

以上是关于使用刷新令牌来获取新的访问令牌反应和节点 js的主要内容,如果未能解决你的问题,请参考以下文章

访问令牌和刷新令牌流程

如何从 passportjs 中的刷新令牌中获取新的 Google oauth 访问令牌

如何使用 JWT 刷新令牌生成新的访问令牌

(JAVA) Google API 分析 - 无法使用“刷新令牌”获取新的“访问令牌”

使用 Angular 和 JWT 令牌持续登录

从passportjs中的刷新令牌获取oauth访问令牌