【发布时间】: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 错误,在这里我将陷入无限的重新加载循环。
有什么想法吗?如何控制令牌到期?
【问题讨论】:
标签: node.js reactjs authentication jwt http-status-code-401