Angular 4 应用程序在浏览器(网站后端)中运行,显示特定用户拥有的服务器数据。
服务器:PHP+MySQL、Zend Framework 3 + Doctrine ORM
Naming:
-
access_token
:生命周期短(1 分钟),允许访问个人资源,携带 user_id,base64 编码,json Web 令牌规范有效。
-
refresh_token
:长生命周期(1周)允许在不提供凭据的情况下检索新的access_token,存储在数据库中,如果需要可以由管理员撤销。
使用刷新令牌的要点是登录时间超过access_token
寿命短(可能永远,如果refresh_token
每次用户授权时都会更新过期时间),仅当不活动时间超过refresh_token
寿命。
刷新令牌存储在数据库中,因此可以轻松撤销。
1. 浏览器尝试进行身份验证
REQUEST:
回复:
用户名和密码已根据数据库进行验证和检查
如果有效:
-
access_token
生成的过期时间为 60 秒
-
user_id
被编码成access_token
-
refresh_token
生成(随机字符串)并保存到db,过期时间1周,(refresh_token不包含在access_token中,它是一个单独的key)
- HTTP 200 正常
如果无效:
之后的行动
如果有效:
- 访问令牌和
refresh_token
存储在浏览器中(auth服务的私有成员变量,浏览器的本地存储)。
看来储存不是一个好主意refresh_token
在本地存储中 - 但这允许“让我保持登录状态”。如果仅将每个浏览器会话存储在私有成员变量中,则用户每次打开浏览器时都需要登录。有任何想法吗?
如果无效:
2. 浏览器向服务器请求受保护的数据
REQUEST:
回复:
- 如果access_token有效,则发送json数据,HTTP 200 OK
- 如果 access_token 无效(例如无法解码),则 HTTP 400 错误请求
- 如果access_token过期,HTTP 401 Unauthorized
响应后采取的行动:
- 如果 HTTP 200:显示数据
- 如果 HTTP 400:重定向到登录页面
- 如果HTTP 401:使用浏览器中存储的refresh_token重试获取新的access_token
3. 重新尝试使用刷新令牌进行身份验证(在 HTTP 401 Unauthorized 之后)
REQUEST:
回复:
- 证实
access_token
(除了过期时间之外的所有内容,使用 \Firebase\JWT)
- 证实
refresh_token
针对数据库(从 access_token 解码的 user_id、字符串和过期时间)
如果有效:
生成新的refresh_token,保存到数据库,更新ttl(或者应该是相同的令牌,仅更新ttl?)
生成新的access_token
HTTP 200 正常
如果无效:
HTTP 401 未经授权
响应后采取的行动:
如果有效:
- 将新的access_key和refresh_key存储在浏览器中
- 使用新的 access_key 重试先前的资源请求
如果无效:
问题
我不喜欢的关键点是access_token和refresh_token存储在同一个地方并以相同的方式发送。也许还有另一种方法可以做到这一点?
- 这个逻辑合理吗?
- 假设这种情况发生在网络应用程序中,是否存在任何安全缺陷?
- 我应该将这两个令牌存储在浏览器的本地存储中吗?
- should
refresh_token
被编码在access_token
?如果它们仍然保存在同一个地方,看起来它可能会被合并到access_token中。有什么理由不这样做?
- 我应该什么时候更新
refresh_token
寿命?
- 有没有开源项目可以看到类似的身份验证实际应用?
- 还有其他建议吗?
关于在哪里存储令牌和安全缺陷(摘自Github用户布雷特邮报 https://github.com/IdentityServer/IdentityServer3/issues/2039#issuecomment-288135399 https://github.com/IdentityServer/IdentityServer3/issues/2039#issuecomment-288135399)请记住:
- 在 localStorage 中存储令牌容易受到xss.
- 在 cookie 中存储令牌容易受到csrf.
最好的选择是防止两者,如下所述:http://www.redotheweb.com/2015/11/09/api-security.html 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 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 https://github.com/authlib/example-oauth2-server
还有其他建议吗?
查看 OpenID Connect 和身份提供商 (IDP),例如 Keycloak。
希望这对您有任何帮助。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)