带有刷新令牌的JSON Web令牌身份验证逻辑

时间:2017-11-22 11:45:45

标签: angular security oauth-2.0 authorization jwt

在浏览器(网站后端)中运行的Angular 4应用程序,显示来自特定用户拥有的服务器数据。 服务器:PHP + MySQL,Zend Framework 3 + Doctrine ORM

命名:

  • access_token:生命周期短(1分钟),允许访问个人资源,携带user_id,base64编码,json网络令牌规范有效。
  • refresh_token:生命周期长(1周)允许检索新的access_token而不提供存储在db中的凭据,如果需要,可以由管理员撤销。

使用refresh_tokens的主要目的是记录超过access_token短生命周期(如果每次用户授权发生时更新refresh_token到期时间可能永远),用户只需提供凭据以防万一不活动的时间超过refresh_token。 刷新令牌存储在db中,因此可以轻松撤销。

1。浏览器尝试进行身份验证

REQUEST:

  • 用户名和密码
  • 发送至/ api / auth

响应:

验证用户名和密码并根据数据库

进行检查

如果有效:

  • access_token生成时间为60秒
  • user_id已编码为access_token
  • refresh_token生成(随机字符串)并保存到db,到期时间为1周,(refresh_token不包含在access_token中,它是一个单独的密钥)
  • HTTP 200确定

如果无效:

  • HTTP 401 Unauthorized

之后的行动

如果有效:

    存储在浏览器中的
  • access_token和refresh_token(auth服务的私有成员varialbe,浏览器的本地存储)。

refresh_token存储在本地存储中似乎不是一个好主意 - 但这样可以让我保持登录状态"。如果仅在私有成员变量中按浏览器会话存储,则用户每次打开浏览器都需要登录。有什么想法吗?

如果无效:

  • 显示错误,建议重试

2。浏览器从服务器

请求受保护的数据

REQUEST:

  • 发送access_token
  • 到/ api / resource

响应:

  • 如果access_token有效,则发送json数据,HTTP 200 OK
  • 如果access_token无效(例如,无法解码),则为HTTP 400 Bad Request
  • 如果access_token已过期,则为HTTP 401 Unauthorized

回应后的行动:

  • 如果HTTP 200:显示数据
  • 如果HTTP 400:重定向到登录页面
  • 如果HTTP 401:使用存储在浏览器中的refresh_token重试获取新的access_token

3。使用refresh_token重试autenticate(在HTTP 401 Unauthorized之后)

REQUEST:

  • 的access_token
  • refresh_token

响应:

  • 验证access_token(除了到期时间之外的所有内容,使用\ Firebase \ JWT)
  • 针对数据库验证refresh_token(user_id从access_token解码,字符串和到期时间)

如果有效:

生成新的refresh_token,保存到数据库,更新ttl(或者应该是同一个令牌,只更新ttl?) 生成新的access_token HTTP 200 OK

如果无效:

HTTP 401 Unauthorized

回应后的行动:

如果有效:

  • 在浏览器中存储新的access_key和refresh_key
  • 使用新的access_key
  • 重试上一个资源请求

如果无效:

  • 显示登录页面

问题

我不喜欢的关键点是access_token和refresh_token存储在同一个地方并以相同的方式发送。也许有另一种方法可以做到这一点?

  • 这个逻辑是否明智?
  • 是否有任何安全漏洞,假设这种情况发生在网络应用程序中?
  • 我应该将这两个令牌存储在浏览器的本地存储中吗?
  • refresh_token编码access_token吗?如果它们仍然保存在同一个地方,则可以将其合并到access_token中。有什么理由不这样做吗?
  • 我应该何时更新refresh_token生命周期?
  • 任何开源项目都可以看到类似的身份验证吗?
  • 还有其他建议吗?

1 个答案:

答案 0 :(得分:0)

关于令牌的存储位置和安全漏洞(摘自Github用户 brettpostin https://github.com/IdentityServer/IdentityServer3/issues/2039#issuecomment-288135399),请记住:

  • 将令牌存储在localStorage中容易受到 xss 的影响。
  • 将令牌中的令牌存储在 csrf 中。

最佳选择是保护两者,如此处所述: http://www.redotheweb.com/2015/11/09/api-security.html

将令牌存储在仅使用http的cookie中,并按照以下建议使用适当的有针对性的 csrf 防御: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet

  

我何时应该更新refresh_token寿命?

如果您要问何时更新刷新令牌,这取决于协议的实施,例如Google Auth服务器发行的刷新令牌永不过期,则当用户撤消对令牌的访问权限时,它们将被撤消。应用程式。但我可以建议几个星期,这样您就不会失去对它的控制。

  

任何开放源代码项目都可以看到类似的身份验证吗?

好吧,您可以下载使用OAuth2的任何项目,例如github上的该项目:https://github.com/authlib/example-oauth2-server

  

还有其他建议吗?

看看OpenID Connect和身份提供程序(IDP),例如密钥克隆。

希望这对您有任何帮助。