我最近决定审查当前的身份验证流和可用的解决方案。简单地说,有两个选项我感兴趣:会话/Cookie和JWT。
让我们检查第一个。会话是";老而金";该技术仍在广泛用于大多数基于服务器的应用程序。
会话/Cookie的优势
- 易于使用
- 已加密
- 防止XSS攻击(带有
httpOnly
标志( - 防止CSRF攻击(带有
sameSite
标志( - 易于设置的过期时间
- 通过设置适当的标题,易于从服务器端进行管理
- 可以使用会话存储进行扩展(例如redis(
缺点
- 小尺寸(4kb(
- 用于基于服务器的应用程序,不适合SPAs(单页应用程序(
- 跨域请求问题
- 由于许多应用程序可以使用单个API,因此很难通过会话管理身份验证
- SSO(单一登录(-如何实现
- 需要额外的服务器来存储会话数据
- 需要为每个请求查询数据库(以检查用户id(
所以JWT在现代世界来解决这些问题。
JWT的优势
- 本质安全
- 无状态,适用于任何平台(网络、移动(
- 最适合Restful API
- 广泛用于SSO(单一登录(
- 不需要在服务器端查询数据库(以检查用户id(,因为令牌可以包含不可变的数据
- 很适合在各方之间安全地传输数据,因为不可能伪造数据
缺点
- 尺寸更大
- 不容易从服务器端进行管理
- 需要从客户端手动发送带有标头的邮件
在这个话题上读了很多之后,我仍然不知道如何正确地处理JWT。让我们来谈谈客户端以及如何存储JWT。
我想,大多数人都觉得在localStorage
中存储JWT很容易,但这当然是个坏主意,因为它不安全,容易受到XSS攻击。饼干?-我认为,可能只是cookie而没有设置会话,但必须努力处理跨域请求,并且不易受CSRF攻击。你知道实现这一目标的正确方法吗?我还有一个大问题-在哪里存放
另一方面,假设我们有SPA,它现在很流行。来自Auth0文档
单页应用程序
如果你有一个没有相应后端服务器的单页应用程序(SPA(,你的SPA应该在页面加载时请求新的令牌,并将它们存储在内存中,而不需要任何持久性。要进行API调用,SPA将使用令牌的内存中副本。
这意味着我必须登录并在每次页面刷新时获得令牌吗?-拜托,这不是办法。我希望用户保持登录状态。
那么,回到带有会话/cookie的服务器端常规web应用程序?我个人更喜欢JWT,那么使用JWT的最佳方式/流程是什么?如果有任何明确的解释,我将不胜感激。非常感谢。
关于如何让用户登录SPA,您可以很好地使用会话。将会话密钥存储在cookie中,然后在加载页面时向后端发送REST API调用以加载用户/会话数据。
或者,在用户加载应用程序时,使用身份验证流将用户重定向到ID服务器。然后,ID服务器可以设置cookie,并管理身份验证,而无需用户再次登录。这与您询问的SPA解决方案类似,但用户不会太注意到。