安全性 - JWT 和 Oauth2(刷新令牌)

Posted

技术标签:

【中文标题】安全性 - JWT 和 Oauth2(刷新令牌)【英文标题】:Security - JWT and Oauth2 (refresh token) 【发布时间】:2017-12-25 21:28:10 【问题描述】:

我有一个 Angular 客户端应用程序和一个 .net Web api 服务器。 我试图了解如何使用令牌以最佳方式实现安全性。 想了几个办法,不知道哪一个最好,也不知道有没有更好的办法。

过期的 JWT

1.用户使用凭据登录 -> 服务器返回一个过期的 JWT(例如从登录时间开始 60 分钟)。在这 60 分钟内对服务器的每个有效请求,服务器都会返回一个新的 JWT 令牌,新的过期时间为 60 分钟。如果用户在 60 分钟内没有发送服务器请求,他必须重新登录。 此解决方案与会话非常相似。

Oauth2 - 我认为我没有正确理解此协议,因此如果我所说的不正确,我深表歉意。

2.用户使用凭据登录 -> 用户获取 refresh_token 和 access_token。 对于每个请求,客户端都会附加 access_token。如果服务器返回 401(未经授权),则客户端使用 refresh_token 创建新的 access_token 并使用新令牌重新发送失败的请求。

对我来说,这个流程中的问题是我不知道我是否因为令牌无效或用户试图访问未经授权的资源而获得了未经授权。

这让我想到了第三种解决方案。

3. 用户使用凭据登录 -> 用户获取 refresh_token、access_token 和 access_token_expiration。当用户想要向服务器创建请求时,他会检查 access_token 是否已过期。如果过期,客户端将请求一个具有新过期时间的新 access_token,然后才执行该请求。

还有 2 个关于 auth2 的小问题:

1.为什么我有refresh_token和access_token?它们都存储在客户端本地存储中。为什么不总是使用 refresh_token?对于服务器来说,有一个 refresh_token 和 access_token 是有意义的,因为 refresh_token 是安全的。

2.刷新令牌是否有过期日期? 如果是这样,我该如何创建新的刷新令牌? 如果没有,提供永远保持联系的能力是不是有点不靠谱?

非常感谢您的帮助

【问题讨论】:

【参考方案1】:

选项 3,使用凭据登录并获取访问令牌、刷新令牌和过期时间是通常的方式。 例如:

   
  "access_token": "eyJ0eXA....CqVJcc",  
  "token_type": "bearer",
  "expires_in": 3599,   
  "refresh_token": "AQAAAN...H2JXjIUAQ"

JWT 访问令牌的过期时间也可以在令牌本身的 payload 字段 exp 中找到,以 UNIX 时间戳的形式:


  ...
  "exp": 1500547257,
  "nbf": 1500543657
   ...

利用这些信息,您可以实施自己的机制来检查您的访问令牌是否仍然有效,并在必要时刷新它。

刷新令牌通常也会过期。当刷新令牌过期时,您需要使用凭据重新开始。

此外,您可以阅读此文章以获取有关该主题的更多信息:https://auth0.com/learn/refresh-tokens/

这里有一个关于 Angular 中处理刷新令牌的教程: http://bitoftech.net/2014/07/16/enable-oauth-refresh-tokens-angularjs-app-using-asp-net-web-api-2-owin/

【讨论】:

以上是关于安全性 - JWT 和 Oauth2(刷新令牌)的主要内容,如果未能解决你的问题,请参考以下文章

撤销 JWT Oauth2 刷新令牌

如何以管理员用户身份撤销用户的访问令牌和刷新令牌?在 Oauth2 中使用 JWT

JWT 访问令牌和刷新令牌安全性

JWT 是不是总是需要访问令牌和刷新令牌?

在没有 OAuth2 的情况下刷新 JWT

为啥使用 JWT 刷新令牌