Validation 通过RESTAPI验证/更改密码

Validation 通过RESTAPI验证/更改密码,validation,rest,restful-url,restful-architecture,Validation,Rest,Restful Url,Restful Architecture,我想通过RESTAPI更改用户密码。这不是忘记或重置密码功能,而是登录用户想要更改其密码 表单需要当前密码、新密码和新密码确认。但是,我希望在用户填写表单字段时对其进行验证。这对于newPassword和confirmNewPassword(客户端)来说是微不足道的,但对于currentPassword来说则不是。当前通过PUT/users/:id对用户对象执行更新。如果传递了密码参数,我会检查currentPassword参数,并确保在保存之前它是正确的。然而,为了验证,我不确定最好的方法 我

我想通过RESTAPI更改用户密码。这不是忘记或重置密码功能,而是登录用户想要更改其密码

表单需要当前密码、新密码和新密码确认。但是,我希望在用户填写表单字段时对其进行验证。这对于
newPassword
confirmNewPassword
(客户端)来说是微不足道的,但对于
currentPassword
来说则不是。当前通过
PUT/users/:id
对用户对象执行更新。如果传递了密码参数,我会检查
currentPassword
参数,并确保在保存之前它是正确的。然而,为了验证,我不确定最好的方法

我还有一个
POST/users/validate
——不确定这是否是最好的。这将验证用户对象的创建和更新,但仅验证属于该用户对象的字段(
电子邮件
用户名
密码
)<代码>当前密码不是其中之一。不知道怎么处理。我考虑过的一些事情:

发布/用户/检查密码
POST/users/validate
(如果参数通过,则添加currentPassword验证,并检查currentPassword是否与用户现有密码匹配)和
POST/users/:id/validate
(对现有用户进行单独验证,需要
currentPassword


如有任何想法或建议,将不胜感激。我的第一个只通过REST API公开功能的应用程序。

您可能会想,为什么需要在输入当前密码后立即对其进行验证。我还没见过这样的网站。第二,有一个只验证某些东西的服务是完全可以的。这被称为“实际的诗句”试图让自己安静下来,我不喜欢/check_password或/validate,因为它们是动词;您的第一个“更新用户”是更好的休息

您可以将currentPassword作为未持久化字段或身份验证标头(用户名:password)的一部分添加到用户对象中


不过,我肯定会将其从PUT改为POST,因为使用相同currentPassword的同一调用不能成功两次(PUT是幂等的)。

我首先要指出,身份验证通常在REST模型之外处理。当用户提供其凭证时,他们没有提供帐户对象状态(REST)的表示;他们也没有得到这样的答复。由于用户帐户资源状态不包括“当前”和“新”密码,因此在请求中同时提供“当前”和“新”密码永远不可能真正符合REST模型,但专业人士通常描述RESTfull的“连续统一体”,其中一些API是完全RESTful的,而另一些则介于RPC和RPC之间(远程过程调用)和REST

在处理数据模型服务的API中有一个RESTful组件,在处理用户帐户的API中有一个RPC组件,这种情况并不少见。您可以在两者之间做出选择。如果您的项目包括管理多个用户帐户的超级用户,我建议尝试将其添加到REST API中。如果每个用户都管理只有自己的帐户,我建议RPC

如果您决定使用REST进行帐户管理,则必须选择适当的HTTP方法(GET、POST、DELETE、HEADERS等)。显然,您需要一种方法来影响服务器上的更改(POST、PUT、DELETE等).与上面用户orbfish的结论相反,我想说,在某些限制条件下,PUT将是一种合适的方法

From,它正式定义了我们的HTTP方法:

方法还可以具有“幂等”属性,因为(除了错误或过期问题外)N>0个相同请求的副作用与单个请求相同。方法GET、HEAD、PUT和DELETE共享此属性。此外,方法选项和跟踪不应有副作用,因此本质上是幂等的

这里的幂等性意味着,如果我们连续n次发出相同的请求,则第n个请求影响下的服务器状态将与第一个请求影响下的服务器状态相同。用户Orbbish正确地注意到,如果我们发出请求:

PUT /users/:id/account {current-password: 'a', new-password: 'b'}
重复一遍:

PUT /users/:id/account {current-password: 'a', new-password: 'b'}
我们的第一个请求应该收到一个指示成功的响应,而我们的第二个请求应该收到一个指示失败的响应。但是,PUT的幂等性只要求服务器的状态在两个请求之后是相同的。它是:在第一个请求之后,用户的密码是“b”,在第二个请求之后,用户的密码是“us”急诊室的密码是“b”

我上面提到了限制。在m次尝试更改密码失败后,您可能希望将用户锁定在外;这将提供针对暴力密码攻击的安全性。但是,这将打破请求的幂等性:发送有效密码请求一次,然后更改密码,再发送m次,然后服务急诊室把你关在外面

通过指定PUT方法,您可以告诉所有客户端,根据需要多次发送请求是安全的。如果我作为客户端发送PUT请求,并且我们的连接被中断,以至于我没有收到您的响应,我知道再次发送PUT是安全的,因为它是幂等的:幂等性意味着如果您收到both请求发送到您的服务器与接收到一个请求是一样的。但是,如果您要因为一个不成功的请求而将我锁定,那么在我知道您是否收到第一个请求之前,发送第二个请求是不安全的

由于这个原因,您可能会考虑修补程序或POST。我建议使用修补程序,而POST被描述为向列表追加新资源或将数据追加到现有资源中,补丁是DES。

PUT /users/fiddlerpianist HTTP/1.1
Content-Type: application/json
Authorization: Basic ZmlkZGxlcnBpYW5pc3Q6bXlub3Rzb2F3ZXNvbWVvbGRwYXNzd29yZA==

{
    "password": "My awesome new password that no one will ever be able to guess!"
}
GET /user/jsmith/pwdchange     List of password change requests (history)
POST /user/jsmith/pwdchange    Create password change request, return id=1
GET /user/jsmith/pwdchange/1   Get password change resource, which would
                               include the outcome (success, failure, etc)