我将首先指出身份验证通常在 REST 模型之外处理。当用户提供他们的凭据时,他们没有提供他们帐户对象的状态 (REST) 的表示;他们收到的回应也不是这样的表示。由于用户帐户资源状态不包括“当前”和“新”密码,因此在请求中同时提供“当前”和“新”密码永远无法真正适合 REST 模型,但专业人士经常描述RESTful 的“连续统一体”,一些 API 完全是 RESTful,而另一些则介于 RPC(远程过程调用)和 REST 之间。
处理数据模型服务的 API 的 RESTful 组件和处理用户帐户的 API 的更多 RPC 组件并不少见。你可以在两者之间做出决定。如果您的项目包含管理多个用户帐户的超级用户,我建议尝试将其硬塞到 REST API 中。如果每个用户只管理自己的帐户,我建议使用 RPC。
如果您决定使用 REST 进行帐户管理,那么您必须选择适当的 HTTP 方法(GET、POST、DELETE、HEADERS 等)。显然,您需要一种会影响服务器更改的方法(POST、PUT、DELETE 等)。与上述用户 orbfish 的结论相反,我要说 PUT 在某些限制下是一种合适的方法。
来自RFC 2616,它正式定义了我们的 HTTP 方法:
“方法还可以具有‘幂等性’,因为(除了错误或过期问题)N > 0 个相同请求的副作用与单个请求相同。方法 GET、HEAD、PUT 和 DELETE 共享这个属性。另外,方法 OPTIONS 和 TRACE 不应该有副作用,因此本质上是幂等的。
这里的幂等性意味着如果我们连续n次发出相同的请求,那么服务器在第n次请求的影响下的状态将与服务器在第一次请求的影响下的状态相同。用户 orbfish 正确地指出,如果我们提出请求:
PUT /users/:id/account {current-password: 'a', new-password: 'b'}
并重复:
PUT /users/:id/account {current-password: 'a', new-password: 'b'}
我们的第一个请求应该收到一个表明成功的响应,而我们的第二个请求应该收到一个表明失败的响应。但是,PUT 的幂等性只要求服务器的状态在两个请求之后相同。它是:在第一次请求之后,用户的密码是'b',在第二次请求之后,用户的密码是'b'。
我在上面提到了限制。您可能希望在m次尝试更改密码失败后锁定用户;这将提供针对暴力密码攻击的安全性。但是,这会破坏请求的幂等性:发送一次有效的密码请求,您更改密码,再发送m次,服务器将您锁定。
通过指定 PUT 方法,您告诉所有客户端可以安全地根据需要多次发送请求。如果我作为客户端发送 PUT 请求并且我们的连接被中断,以至于我没有收到您的响应,我知道再次发送我的 PUT 是安全的,因为它是幂等的:幂等性意味着如果您收到两个请求,它将与您的服务器一样,只是接收一个。但是如果你因为一个不成功的请求而将我锁在外面,那么在我知道你是否收到第一个请求之前,发送第二个请求是不安全的。
出于这个原因,您可能会考虑 PATCH 或 POST。我建议使用 PATCH。POST 被描述为将新资源附加到列表或将数据附加到现有资源,而 PATCH 被描述为对已知 URI 的资源的“部分更新”。与 PUT 不同,PATCH 不必是幂等的。