javascript - 如何使用 refresh_token 在 Oauth 2.0 中实现记住我的功能?
问题描述
我已经阅读了很多资料,包括 OAuth 2.0 的 RFC,以使用此协议进行安全登录。我实现的流程是授权码授予,因为我有一个安全的 NET CORE 后端来存储客户端密码。我已经按照 RFC 或其他 Oauth 2.0 实现工作流程表中的描述实现了该协议。
目前我有 access_token 和 refresh_token,但我希望实现记住我的功能。我以不同的方式思考它,但我不知道如何以安全的方式实现它。
如果我将刷新通过服务器保存在浏览器的http安全cookie中,我很容易受到CSRF攻击,如果我将它保存在本地存储中更糟糕,因为我很容易受到XSS攻击并且可能被窃取.
简而言之,我需要缓解 XSS 和 CSRF 漏洞,具有记住我的功能。(我也考虑过使用浏览器的同站点 cookie 属性来缓解 se CSRF 漏洞,但我需要获得背靠背兼容性,并且此功能仅在最新版本的浏览器中可用)。
我的问题是:我如何实现记住我的功能,同时兼顾安全方面?
解决方案
如果您的应用程序存在 XSS 漏洞,那么您将令牌保存在内存(变量)还是 localStorage 中都没有关系。恶意代码访问它不会有问题。因此,我认为在 localStorage 中保留“记住我”信息不会降低您当前的安全级别。为了保护您的应用程序免受 XSS 攻击,您可以使用内容安全策略之类的东西,以便只执行您信任的 JavaScript 代码。有关详细信息,请参阅OWASP XSS 预防备忘单。
我认为您可以将访问令牌保存在 sessionStorage 而不是变量中,这样用户在重新加载页面时就不必登录。
如果您将“记住我”信息存储在仅 HTTP 的 cookie 中,它可能会使您的应用程序容易受到 CSRF 攻击,但同样,有一些方法可以防止它(OWASP CSRF 预防),例如 CORS 并在每个 cookie 中发送一个额外的令牌请求,需要通过 JavaScript 代码从 cookie 中读取。
“记住我”功能可能会增加某种风险,因为用户会长时间保持登录状态。因此,由您来评估用户的风险和便利之间的平衡。
您可以查看OAuth 2.0 for Browser-Based Apps。它不讨论“记住我”功能,但讨论了良好实践和安全注意事项。
推荐阅读
- reactjs - React Redux 仅从 firebase 加载数据一次
- javascript - 完成后光滑的滑块幻灯片视频
- sql - 在 SQL 中替换文本字段中的值
- java - Spring Data REST 将导出其所有属性(id 除外)。
- android - WorkManager Data.Builder 不支持 Parcelable
- python-2.7 - 如何使报告的页脚固定在底部
- odbc - ODBC MS 查询日期参数
- postgresql - 在选择 INSERT 或 UPDATE 时,Doctrine 是基于什么?
- python - 在python中动态删除日志文件
- apache-spark - Pyspark:Dstream 选择列