javascript - 如果存储在本地存储中,检查 jwt 令牌过期状态的最佳方法
问题描述
我想检查令牌是否在客户端过期。
我的令牌存储在本地存储中。
现在我要做的是:调用服务器以检查它是否有效,但我只在路径为:https:exp.com/
代码:
useEffect(() => {
verifyToken(auth.token).then((res) => {
if (res.status !== 'success' && res.message === 'Token expired') {
signoutClient(() => {
router.push('/auth/login');
});
}
});
}, [auth.token, router]);
现在的问题是,如果用户直接转到另一个 url exp 怎么办:https:exp.com/helloworld
我正在考虑使用套接字,但我不知道它是否可以工作。
想法是:客户端保持监听,每当令牌过期服务器发出消息。
关于我该怎么做的任何想法?
解决方案
有不同的技术。
请注意,在两台不同的机器上处理时间(在这种情况下是过期)可能会由于时间抖动或时钟错位而导致问题,因此并不是那么简单
被动到期
我最喜欢的模式是出现专用服务器错误。
当令牌过期时,您的服务器应该以特定错误响应(与401 Unauthorized
由于角色访问权限不同)。然后向客户端添加一个 HTTP 中间件:
- 检测到此错误响应
- 删除本地令牌并导航到
/auth/login
或者,如果您有renew token
:
- 检测到此错误响应
- 试图更新
JWT
- 成功时重复原始请求或失败时导航到身份验证页面。
这是一个被动系统,允许您将JWT
视为晦涩难懂的字符串,并且不存在与时间相关的问题。
返回一个单独的字段
如果出于安全原因,您想在会话到期时隐藏敏感信息,即使用户没有与 UI 交互(如银行网站那样),您需要知道令牌何时到期。一种常见的技术是将过期时间与令牌一起返回(在身份验证响应中)。
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.JFDV4mOKKh0sMfkBKvsbvm8iWjHEGBXtPvC49ob3qiI",
"expiresAt": 1234567890
}
甚至更好
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.JFDV4mOKKh0sMfkBKvsbvm8iWjHEGBXtPvC49ob3qiI",
"expiresIn": 600
}
第一个返回令牌到期相对于服务器时间的 UNIX 时间。这会受到时间抖动或时钟失调的影响(这可能会导致错误)。第二个更好,因为它让 UI 知道令牌将在多少秒内(因为收到响应)过期,然后可以用来根据本地时钟计算 UNIX 时间。
移除一个小的时间步长以避免时钟抖动和时钟漂移问题是很常见expiresAt
的expiresIn
。
解析 JWT
如果您没有其他解决方案,您可以随时解析JWT
:
const JWT = `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjEyMzQ1Njc4OTAsIm5hbWUiOiJKb2huIERvZSIsImlhdCI6MTUxNjIzOTAyMn0.1c_yQjnMZfKUb4UTDE_WvbC71f8xxtyMsdqKKkI1hF8`;
const jwtPayload = JSON.parse(window.atob(JWT.split('.')[1]))
console.log(jwtPayload.exp);
推荐阅读
- asp.net - System.Data.Entity.Validation.DbEntityValidationException:'验证一个或多个实体失败
- react-native - React Native 如何绘制曲线
- java - Java 11 和 jacorb。ClassNotFoundException: javax.rmi.CORBA.Stub
- python - 适合 WCS 以治愈
- javascript - 在 2048 游戏中只向右移动一步
- angular - 使用 RxJS observables 考虑所有输入的 MIDI 设备
- excel - 查找某个标题并在其下方复制一定数量的条目
- c# - 将值从 DateTime 分配给可为空的 DateTime 总是给出种类“未指定”而不是“Utc”
- python-3.x - 为什么在单元测试中列出 value 而不是 str?
- java - 尽管实现了“getColumnClass”,但 JTable 显示 true/false 而不是 CheckBox