如果所有凭据都存储在客户端上,如何安全地处理 REST 身份验证?

How is REST authentication handled securely if all the credentials are stored on the client?

我正在阅读此文档中的 API 最佳实践

http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api

我以前构建过简单的自定义 REST API,我觉得我也设法保护了它们。之前,我在服务器上生成了客户端的身份验证"token" 或护照,并将其打印在页面上。这个想法是客户端既不能猜测也不能轻易地逆向工程该令牌是如何生成的,因为生成它的函数对客户端是不可见的。这是糟糕的用户体验,因为令牌会在一定时间后过期,结果页面会过期并且无法向 API.

发出新请求

但是,我仍然不确定在从服务器 "lightly decoupled" 获得的客户端上会发生这种情况,因为 Web 服务器没有为每个请求提供页面。因此,客户端需要事先了解有关身份验证的信息。

我感觉到这种模式会迫使我在客户端生成或存储 API 身份验证详细信息,任何人都可以看到。我发现这种做法是不安全的,我想避免这种做法,但考虑到我所知道的信息(我承认这些信息很少),这是不可能的。

关于 API 安全和身份验证,我从这个模式中遗漏了什么?

你用 OAuth 标记了你的问题,但你没有提及它并保持问题广泛。因此,我发现通过向您展示一个非常好的示例来讨论这个概念是合适的,该示例存储身份验证 session client-side,同时使用不同的技术(即 JSON Web Token (JWT)

强制执行安全性]

基本流程如下:

  1. 客户端登陆服务器并出示其凭据
  2. 服务器验证凭据,构建 JWT 令牌并将其注入 HTTP Header
  3. 客户端自动为每个后续请求使用此 HTTP Header
  4. 服务器验证令牌,如果验证成功,则提供资源

整个过程的重点是token结构及其生成。基本上,令牌保存客户端的身份验证状态。例如,它可以包含客户的角色。

这里主要关注的是防止客户端伪造假令牌。确保完整性的技术由来已久,称为HMAC。基本上,服务器注入的JWT构建如下

header : payload : HMAC[header,payload,secret]

HMAC 是一种加密散列,只能由知道秘密的实体生成。那么,让我们来玩一个攻击场景。

  1. 客户端登陆服务器并出示其凭据
  2. 服务器验证凭证并像这样构建 JWT 令牌

    header : { "alg": "HS256", "typ": "JWT" } { "sub": "1234567890", "name": "John Doe", "admin": false <--- original role } HS256{...}

  3. 客户端试图篡改消息如下:

    header : { "alg": "HS256", "typ": "JWT" } { "sub": "1234567890", "name": "John Doe", "admin": true <--- tampered role } HS256{...}

但它不知道这个秘密,所以它无法计算出正确的 HS256 代码。

  1. 服务器获取客户端发送的header和篡改的payload,重新计算HMAC并将其与请求中发送的进行比较。它们不匹配,因此 client-session 已被更改。游戏结束。

这是让客户端存储 session 同时加强安全性的一种非常有趣的方式。