通过REST API验证/更改密码

Kar*_*eem 5 validation rest restful-url restful-architecture

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

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

我也有POST /users/validate- 不确定这是否也是最好的.这证实一个用户对象都创建和更新,但仅验证属于用户对象(字段email,username,password).currentPassword不是其中之一.想知道如何处理这个问题.我考虑过的一些事情:

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

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

JAS*_*ilz 8

我首先要指出的是,身份验证通常是在REST模型之外处理的.当用户提供他们的凭证时,他们没有提供他们的帐户对象的状态(REST)的呈现; 他们也没有得到这样的回应.由于用户帐户资源状态不包括"当前"和"新"密码,因此在请求中提供"当前"和"新"密码永远不会真正适合REST模型,但专业人员通常会描述RESTfulness的"连续统一体",其中一些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'}
Run Code Online (Sandbox Code Playgroud)

并重复一遍:

PUT /users/:id/account {current-password: 'a', new-password: 'b'}
Run Code Online (Sandbox Code Playgroud)

我们的第一个请求应该收到指示成功的响应,我们的第二个请求应该收到指示失败的响应.但是,PUT的幂等性只要求服务器的状态在两个请求之后都是相同的.它是:在第一次请求之后,用户的密码是'b',在第二次请求之后,用户的密码是'b'.

我提到了上面的限制.在m尝试更改密码失败后,您可能希望锁定用户; 这将提供防止暴力密码攻击的安全性.然而,这将打破请求幂等:发送一个有效的密码请求一个时间和您更改密码,发送中号更多的时间和服务器锁定你.

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

因此,您可以考虑使用PATCH或POST.我建议使用PATCH.虽然POST被描述为将新资源附加到列表或将数据附加到现有资源,但PATCH被描述为对已知URI上的资源的"部分更新".与PUT不同,PATCH不一定是幂等的.


orb*_*ish 6

我不喜欢/ check_password或/ validate因为它们是动词; 你的第一个"更新用户"是更好的REST.

您可以将currentPassword作为未显示的字段添加到User对象,或者作为Authentication标头的一部分(用户名:密码).

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


sui*_*ing 1

您可能会想为什么需要在输入当前密码后立即对其进行验证。我还没有看到有网站这样做。其次,拥有一个仅验证某些内容的服务是完全可以的。这就是所谓的实用诗句,打败自己试图保持安静