我有一个基于Koa的Node.js后端用于我的个人/业余爱好应用程序。
我用JWT令牌实现了会话处理。客户端(AngularJS)在成功登录后获取令牌,并将令牌存储在某个地方(目前在sessionStorage中,但出于这个问题的目的,这不重要)。
我有两个问题:
2.1。JWT是短命的,比如说15分钟。如果后端服务器使用401个未经身份验证的“无效令牌”(我猜这是koa-jwt的默认行为)进行应答,那么我会自动注销我的客户机并要求重新验证。但是,我还设置了一个补充中间件,它是后端链中的最后一个中间件,用于重新创建更新到期的令牌,客户端也将用刷新的令牌替换现有的令牌。因此,如果用户是活动的,并且使用应用程序,那么如果成功,每个受保护的API调用都会创建一个新的令牌来替换旧的令牌。
2.2。JWT被设置为长寿,比如1周,如果它到期,我将从客户端选择重新身份验证。
2.3。复制https://www.rfc-editor.org/rfc/rfc6749#section-1.5。在这里,在成功身份验证之后创建JWT令牌时,我们发送一个access_token和一个refresh_token。当access_token过期,服务器使用HTTP401“无效令牌”(koa-jwt默认值)进行响应时,客户端将refresh_token发送到后端,以要求一个新的access_token (可选为新的refresh_token)。在这种情况下,我不完全理解refresh_token是如何根据旧的access_token进行验证以提供新令牌的?或者为什么我们需要一个refresh_token?
任何关于高级主题(JWT更新和JWT过期)的一般性建议都是有帮助的。
发布于 2016-10-03 09:29:09
从底部开始,我将忽略刷新令牌,因为我认为它们不会在这里帮助您。它们通常针对其他情况,客户端应用程序可以提供比用户浏览器更安全的存储--比如本地移动应用程序或服务器端web应用程序。
刷新令牌是长寿的。这意味着当客户端从服务器获得一个令牌时,必须安全地存储此令牌,以防止潜在攻击者使用该令牌,因此,将其存储在浏览器.中是不安全的。
(重点是我的;源刷新令牌)
这意味着选项2.3基本上与2.2相同,这是一个不错的选择。使用长会话时间的web应用程序并不少见。如果您的应用程序不是很敏感,那么使用长会话来改善用户体验是可以接受的。例如,Django使用默认的两周作为会话cookie的使用时间。见年龄。
其余的选项(2.1)通常称为滑动会话。会话超时时间很短,但只要用户在此间隔内继续使用应用程序,会话就会自动更新。这可能是最常见的方法,或者至少是我使用时间最多的方法,所以我有偏见。我要注意的唯一一点是,滑动会话通常使用存储为cookies的不透明会话标识符来实现,然后使用存储在服务器上的实际会话数据实现。
您的方法有点不同,因为您在浏览器本地存储中存储了一个无状态JWT令牌(它包含实际的用户数据)。正如您所说的,为了更新令牌,您必须生成一个新的令牌,因为您必须生成一个新的签名。
该签名用于验证JWT的发送方是否是它所称的,并确保消息不会以这种方式更改。
(重点是我的;源JSON网络令牌)
话虽如此,我仍会考虑以下几点:
尽管如此,您还应该考虑到JWT不是很大,但是如果您决定自动更新,它们仍然是一种开销。您可以通过选择20分钟的会话持续时间来稍微减轻这种情况,并且只在一半的会话结束后执行自动更新。
另一点是,应用程序中的XSS这样的漏洞将向攻击者公开访问令牌,因为注入的脚本将能够从localStorage/sessionStorage中读取,这可能是另一个有利于HTTP存储的漏洞。
发布于 2016-10-03 09:25:40
在我开始第一个问题之前,我想回答你的第二个问题。
基本上,您提到的第三个选项是更新您的访问令牌的最佳方式。访问令牌应该是短生存期(~5分钟),并且刷新令牌的寿命更长。当访问令牌过期时,将刷新令牌发送到后端,并获得一个新的访问令牌。所以你的反应应该是这样的:
{
"token_type":"bearer",
"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiVlx1MDAxNcKbwoNUwoonbFPCu8KhwrYiLCJpYXQiOjE0NDQyNjI4NjYsImV4cCI6MTQ0NDI2Mjg4Nn0.Dww7TC-d0teDAgsmKHw7bhF2THNichsE6rVJq9xu_2s",
"expires_in":10,
"refresh_token":"7fd15938c823cf58e78019bea2af142f9449696b"
}因此,我们的想法是将应用程序分离到授权服务器(它生成访问令牌/刷新令牌)和资源服务器(验证访问令牌并访问资源)。可以维护架构,以便根据授权服务器中的访问令牌验证刷新令牌。请参考此链接中提到的模式部分,它可能会给您一些想法。Oauth2。您可以根据需要修改架构。您不需要为每个请求调用发送刷新令牌和访问令牌。刷新令牌只能发送到授权服务器以生成新的访问令牌。如何生成刷新令牌?如果我使用的是Java,我将使用UUID.randomUUID()生成唯一的刷新令牌。
现在要回答第一个问题,如果您想要根据更新的用户记录更新JWT有效负载,那么您可以使用相同的刷新令牌来生成一个具有更新的有效负载的新访问令牌。逻辑保持不变,因为如果用户记录中存在电话号码,它将被添加到有效负载中,如果没有,则在有效负载中为空。
使用Refresh令牌的主要优点是可以在任何时候使用Refresh令牌更新访问令牌。
https://stackoverflow.com/questions/39825953
复制相似问题