我一生都无法弄清楚如何在不中断用户原始请求的情况下刷新用户的身份验证令牌...
我有一个解决方案,但有一个问题。
假设用户登录,我的服务器使用 JWT 生成一个 accessToken 和 refreshToken:
accessToken 保存在 cookie 中,它的生命周期很短,比如 15 分钟,其到期日期直接发送给用户
refreshToken直接发送给用户并保存在 localStorage,它的寿命很长,比如说30天
对于每个涉及访问资源的请求,服务器都会检查 accessToken cookie 的有效性。假设用户想要编辑他们的个人资料:/profile/edit,正文数据如下:{name: "My New Name"}
如果accessToken无效(例如过期),则用户的请求 被拒绝,他们将被重定向回登录页面。
为了确保 accessToken 不会失效,用户的网络浏览器将检查 accessToken 的过期日期 (localStorage.getItem("accessTokenExpirationDate"),例如每 1 秒
如果accessToken即将过期,用户将发送带有数据的/refresh GET请求:{refreshToken: localStorage.getItem("refreshToken")
服务器然后刷新访问/刷新令牌并相应地设置它们
这可行。但问题是,如果用户关闭浏览器,例如 30 分钟后返回,然后他们返回网站,他们将被重定向到登录页面,尽管仍然具有有效的刷新令牌。由于计时器没有运行来主动检查访问令牌过期,因此从未发送 /refresh 请求...
是否有其他解决方案来确保用户不会被重定向到登录页面?如何在同一请求上刷新令牌?
或者我当前的解决方案是否有更新,以便如果用户关闭浏览器然后返回,他们将能够继续正常使用网站资源而无需重新登录?
折扣,用户已经登录时无需使用登录页面。
如果您想使用它,则需要断开连接。
重定向到登录页面时,如果刷新令牌有效,则会发出接收访问令牌的请求。如果请求成功 您将返回到“抛出”未登录用户的上一个页面。
从您的问题中我了解到您将刷新令牌存储在本地存储中。 警告!请找到存储刷新令牌的替代方案,例如 http-cookie。 您面临 XSS 攻击
function isAlreadyLoggedin(){
// load refresh-token exp with convert to Date
const refreshTokenExpirationDate = new Date(localStorage.getItem("refreshTokenExpirationDate"));
// case: Refresh-token exp, User must re-login!
if (Date.now() > refreshTokenExpirationDate) {
return;
}
// load access-token exp with convert to Date
const accessTokenExpirationDate = new Date(localStorage.getItem("accessTokenExpirationDate"));
if (Date.now() > accessTokenExpirationDate) {
if (renewAccessToken() === true) {
// browser automatic back to http://your-url/profile/edit
window.history.back();
}
}
}
isAlreadyLoggedin();