REST API:简单的基于令牌的身份验证 - 安全性?

REST API: Simple token-based authentication - security?

我有一个 REST API,我正在寻找一种简单的方法来进行基于令牌的安全身份验证。因为我读到像 OAuth 这样的协议非常复杂,所以我想实现一种更简单的方法。常见的方法有哪些?那么下面程序的安全性如何?

  1. 客户端输入电子邮件和密码 -> 将其发送到 REST API(通过 HTTPS)
  2. API验证用户
  3. 如果登录数据正确,API 会生成一个唯一的 API 令牌,将其保存在数据库中供用户使用,然后将其发送回客户端
  4. 令牌存储在客户端网络存储
  5. 对于以下请求,客户端每次都必须发送token并且API每次都必须检查token
  6. 注销时,token从webstorage和数据库中删除(用户再次登录时生成新的token)

这种方法是否存在严重的安全问题?还是可行?

非常感谢

简短的回答是这种方法的概念没有重大安全问题,但实施是关键,这可能是我最重要的一点。

自定义实现问题

你描述的基本上是一个普通的旧session。这里的 "token" 只是一个 session id。 Web 应用程序多年来一直以这种方式工作。已知的高质量实现可以避免 session 固定、弱或不安全的 session id 生成等,还有一长串 session 管理漏洞。如果您尝试自己实施它,那么要使其正确和安全并不容易。因此,如果您打算这样做,只需使用已知的良好实现即可。

XSS 问题

不过有一点不同,你想将你的 "token" (session id) 存储在 "webstorage" 中,它可以是 localStorage、sessionStorage 或WebSQL 基本上。传统的 session 管理将 session id 存储在 cookie 中是有充分理由的——可以更好地保护 cookie 免受 cross-site 脚本(XSS)攻击。如果 session cookie 被标记为 httpOnly,Javascript 将无法访问它,它只会被浏览器发送回同一服务器(实际上是源)。这对于任何其他存储都是不可能的,这意味着如果您的站点(同一来源的任何页面)中存在 XSS 漏洞,则用户令牌可能会被盗。这明显不如使用 httpOnly cookie 安全。

在现代 Web 应用程序中,这是一个可以接受的风险很多次。这主要发生在您想要将相同的令牌发送到多个服务器(源)时。使用 httpOnly cookie 是不可能的。但是,如果您的令牌存储在数据库中,那么出于架构原因,您可能不想这样做。

CSRF 问题 - 已阻止

另请注意,尽管这种设计在 headers 中发送令牌几乎默认情况下可防止 cross-site 请求伪造 (CSRF)。所以好处是你不必(太多)关心 CSRF,但这是以 XSS 影响为代价的,并且在大多数情况下超过了这个好处。

状态问题

最后一点,这不是安全问题,但使用您的设计,您的 API 将是有状态的,它将为每个客户端存储一个状态。这不是很好,因为正如您所说的那样,您将不得不去数据库检查每个请求的令牌(或者您可以深入缓存和类似的复杂性来源)。然后想象一下,如果您的服务需要在多个服务器上 load-balanced、运行 并具有多个数据库副本实例,会发生什么情况。因此,现代 API 设计的目标是无状态——不为客户端存储状态。这就是(真正的)令牌认证的亮点,令牌不需要存储到数据库中,它们本身就是真实的。这就是 token-based 身份验证真正有意义的地方,而不是在简单的情况下,普通的 session id 也可以,并且会更安全。