基于令牌与cookie两种身份验证方式的适用场景?


对于基于令牌的身份验证:

  1. 用户访问网页
  2. 前端查询 localStorage 的令牌以确定用户是否经过身份验证
  3. 在前端:如果经过身份验证,则转到 7,否则呈现登录表单
  4. 用户通过后端进行身份验证
  5. 后端在响应正文中发送 API 令牌
  6. 前端将令牌存储在例如 localStorage 中(步骤 2 现在将成功并跳过重新身份验证)
  7. 前端呈现经过身份验证的页面
  8. 对于每个后续请求,前端显式设置带有令牌的“Authorization”标头

对于基于 cookie 的身份验证:
  1. 用户访问网页
  2. 前端查询,例如第一次渲染时的 /api/users/whoami (浏览器发送任何存在的 cookie)
  3. 后端读取/验证 cookie 并响应一些指示身份验证(或不身份验证)的正文内容
  4. 在前端:如果经过身份验证,则转到 8,否则呈现登录表单
  5. 用户通过后端进行身份验证
  6. 后端设置 auth cookie 并响应成功消息
  7. 浏览器隐式保留 cookie(步骤 2 现在将成功并跳过重新身份验证)
  8. 前端呈现经过身份验证的页面
  9. 对于每个后续请求,前端不执行任何操作(cookie 由浏览器隐式发送)

优缺点:
基于令牌:

  • XSS 可以读取 localStorage 并窃取令牌(有一些方法可以缓解这种情况)
  • XSS 只能使用其执行来发出经过身份验证的 API 请求
  • 没有cookie,没有CSRF

基于cookie
  • XSS 只能使用其执行来发出经过身份验证的 API 请求
  • 有 cookie,但(应该)使用 `HttpOnly`/`Samesite`/`Secure` 可以缓解 CRSF

使用基于令牌的方法则增加了 XSS 攻击面,并且必然会增加前端的复杂性。
 cookie 的身份验证的唯一 缺点是:您的前端需要在首次呈现时发出 Web 请求,例如 /api/ users /whoami 以确定其用户数据以及后端是否已验证经过身份验证的会话。大规模地这些额外的网络请求可能是不受欢迎的。

其他观点:
1、我猜是因为有人说过,API 都必须是无状态的。所以现在我们找到了变通方法,用无状态 API 构建有状态应用程序。
此外,还有整个 Oauth2 热潮,人们认为每个使用 API 的应用程序都应该使用 Oauth2 进行连接,即使它们从未要求过任何形式的单点登录。
所以是的......我使用 API 标记进行后端到后端的通信,但我认为在大多数情况下,前端到后端的通信最好使用 cookie 和简单的文本标记(而不是 JWT)。
一个有效的用例是,如果您创建的移动应用程序将使用与网站相同的应用程序接口,因为您的移动应用程序很可能无法使用 cookie。

流行的方法是使用 JWT 并将它们放入本地存储中,然后将它们与“Authorization:Bearer”标头中的每个请求一起发送。
但实际上,很少有情况需要像JWT 这样复杂的东西。
您可以生成一个随机字符串(只要您使用加密安全的随机生成器),存储它,并将其与前端发送给您的内容进行比较。

想一想,本地存储和“Authorization:Bearer”标头有一个很好的用例,即移动APP。 你不能在APP使用 cookie。因此,如果您在应用程序中使用一种方法,那么您的网站也可以使用相同的方法。

就后端复杂性而言,我觉得验证数字签名比在数据库中查找令牌更快/更便宜/更简单。如果签名通过,那么您就可以开始了。
除非你也想在后端支持令牌撤销。在这种情况下,您仍然需要执行此比较查找。但希望在实践中撤销列表很小(或为空),并且此步骤通常几乎为零时间。

2、基于令牌的身份验证对于第三方身份验证最有用:客户端请求令牌,用户被重定向到身份提供者,用户登录并将令牌发送到客户端。客户端现在可以代表用户向也信任身份提供商的服务提供商发出基于令牌的请求。这有助于允许跨站点身份验证,而无需共享密码或 cookie。请注意,此令牌根本不需要发送给用户。
您可以向用户发送会话 cookie,并将令牌与会话一起存储。对于涉及单个站点的大多数用例,我认为基于令牌的身份验证没有任何优势。

3、如果您有简单的一对一客户端服务器关系,则 Cookie 是 100% 可行的方法。它很简单并且更容易确保安全,但是......在更大更复杂的企业架构中,这种服务器客户端直接关系并不总是如此。

JWT 身份验证可以更加灵活,并且适用于拥有多个 API、多个不同页面或使用相同 API 的移动应用程序的情况。

例如。一家大公司可能有 8 个不同的 API,由不同的团队用不同的语言编写来维护。像这样的公司将推出一个身份验证服务器来处理所有身份验证并分发所有令牌。这意味着一旦您拥有令牌,您就拥有了一个可以与所有 API 安全通信的通用接口。

有些模式涉及 API 网关,该网关充当所有 API 的前门。基于 Cookie 的功能非常有限。JWT 意味着几乎任何东西都可以安全地调用您的 API,而不仅仅是浏览器。

Cookie 在本机应用程序中也不起作用。您习惯使用手机上的应用程序保持登录状态的流程是 JWT 刷新 Oauth 流程。这意味着在您的网页的基于 cookie 的身份验证流程之上维护一个身份验证服务器。这是没有意义的,所以你只需使用 JWT 和 Oauth/OpenID 等来完成所有事情。

总结一下 cookies 很棒,安全简单。基于令牌的方式更加灵活/可互操作,但在其他方面可能更差。


4、许多 Web 框架仍然使用 Cookie;
令牌通常用于保护 API,因为它们不仅可以被浏览器使用,还可以被许多客户端使用。

随着 SPA(单页应用程序)的兴起,许多应用程序开始将其后端转变为 Rest(或类似的)API。
有一种常见模式称为前端后端 (BFF)。当特定后端处理令牌并且 spa 可以再次使用 cookie