处理JWT到期和JWT有效负载更新

JavaScript KoaJS

宝儿

2020-04-03

我的个人/爱好应用程序有一个基于Koa的Node.js后端。

我使用JWT令牌实现了会话处理。客户端(AngularJS)在成功登录后获取令牌并将令牌存储在某个位置(当前存储在某个位置,sessionStorage但出于此问题的目的,这无关紧要)。

我有两个问题:

  1. 当我需要更新JWT代表的用户记录时,例如,用户打开了双重身份验证(2FA),因此我要求他提供他的电话号码,并且我想在用户记录中设置该电话号码。目前,在成功验证电话号码后,我打电话给后端以更新用户记录,并使用更新后的用户记录创建新的JWT令牌(我从JWT令牌中排除了敏感信息(如哈希密码),但我希望包括供客户端使用的电话号码)。是否可以在某些凭据更改时创建新令牌并使用此新令牌更新现有的客户端令牌?我应该永远不要创建另一个令牌,仅创建一个令牌并且仅在成功身份验证之后创建吗?然后如何更新令牌中的有效负载?

  2. How should I handle expired JWT tokens? In my mind I have 3 (possible) scenarios:

    2.1. The JWT is set to short living, say 15 minutes. If the backend server replies with a 401 Unauthenticated 'Invalid token' (I guess this is the default behavior of koa-jwt) then I automatically log-out my client and require re-authentication. But I also set up a complementary middleware, which is the last in the chain on the backend to re-create the token with a refreshed expiry and the client would also replace the existing token with the refreshed one. So if the user is active and uses the application every protected API call, in case of success, would create a new token to replace the old token.

    2.2. The JWT is set long-living, say 1 week, and if it expires I opt-in re-authentication from the client.

    2.3. Copy https://tools.ietf.org/html/rfc6749#section-1.5. Here when creating the JWT token after a successful authentication we send an access_token as well as a refresh_token. When the access_token is expired and the server responds with HTTP 401 'invalid token' (koa-jwt default) then the client sends the refresh_token to the backend to require a new access_token (and optionally a new refresh_token). In this case I don't fully understand how the refresh_token is verified against the old access_token to provide a new token? Or why do we need to have a refresh_token?

Any generic advice on the upper topics (JWT updates and JWT expiration) would be helpful.

第3944篇《处理JWT到期和JWT有效负载更新》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

1个回答
Eva凯 2020.04.03

在开始第一个问题之前,我想回答您的第二个问题。

基本上,您提到的第三个选项是续订访问令牌的最佳方法。访问令牌的寿命应较短(〜5分钟),刷新令牌的寿命应更长。当您的访问令牌过期时,将刷新令牌发送到后端并获取新的访问令牌。所以您的回应应该是这样的:

{
"token_type":"bearer",
"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiVlx1MDAxNcKbwoNUwoonbFPCu8KhwrYiLCJpYXQiOjE0NDQyNjI4NjYsImV4cCI6MTQ0NDI2Mjg4Nn0.Dww7TC-d0teDAgsmKHw7bhF2THNichsE6rVJq9xu_2s",
"expires_in":10,
"refresh_token":"7fd15938c823cf58e78019bea2af142f9449696b"
}

因此,我们的想法是将您的应用程序分为Authorization Server(生成访问令牌/刷新令牌)和Resource Server(验证访问令牌并访问资源)。您可以维护一个架构,以针对授权服务器中的访问令牌来验证刷新令牌。请参考此链接中提到的架构部分,这可能会给您一些想法。Oauth2您可以根据需要修改架构。您无需为每个请求调用发送刷新令牌和访问令牌。刷新令牌只能发送到授权服务器以生成新的访问令牌。如何生成刷新令牌?如果使用Java,则将用于UUID.randomUUID()生成唯一的刷新令牌。

现在回答第一个问题,如果您想基于更新的用户记录来更新JWT有效负载,则可以使用相同的刷新令牌来生成具有更新的有效负载的新访问令牌。逻辑保持不变,因为如果电话号码存在于用户记录中,它将被添加到有效负载中,如果不存在,则在有效负载中将为空。

使用刷新令牌的主要优点是访问令牌可以随时使用刷新令牌进行续订

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android