构建RESTful资源以重置密码的正确方法是什么?
此资源旨在成为丢失或忘记密码的人的密码重置程序.它使旧密码无效并通过电子邮件向他们发送密码.
我有两个选择:
POST /reset_password/{user_name}
要么...
POST /reset_password -Username passed through request body
我很确定请求应该是POST.我没有信心选择一个合适的名字.而且我不确定是否应该通过URL或请求正文传递user_name.
我们PUT
在api/v1/account/password
端点上发出请求,并要求使用相应帐户电子邮件的参数来标识用户要重置(更新)密码的帐户:
PUT : /api/v1/account/password?email={email@example.com}
注意: 正如@DougDomeny在他的评论中提到的那样,将电子邮件作为URL中的查询字符串传递是一种安全风险.使用时不会暴露GET参数https
(并且您应始终https
对此类请求使用正确的连接),但还存在其他安全风险.您可以在此博客文章中阅读有关此主题的更多信息.
在请求正文中传递电子邮件将是将其作为GET参数传递的更安全的替代方法:
PUT : /api/v1/account/password
请求机构:
{ "email": "email@example.com" }
响应具有已202
接受的响应含义:
该请求已被接受处理,但处理尚未完成.该请求最终可能会或可能不会被执行,因为在实际处理时可能不允许该请求.没有用于从诸如此类的异步操作重新发送状态代码的工具.
用户将收到电子邮件email@example.com
并处理更新请求取决于使用电子邮件中的链接执行的操作.
https://example.com/password-reset?token=1234567890
打开此电子邮件中的链接将指向前端应用程序上的重置密码表单,该表单使用链接中的重置密码令牌作为隐藏输入字段的输入(该令牌是链接的一部分作为查询字符串).另一个输入字段允许用户设置新密码.确认新密码的第二个输入将用于前端验证(以防止拼写错误).
注意: 在电子邮件中我们还可以提到,如果用户没有初始化任何密码重置,他/她可以忽略该电子邮件并继续使用他/她当前密码的正常应用程序
当使用新密码和令牌作为输入提交表单时,将执行重置密码过程.表单数据将PUT
再次与请求一起发送,但这次包括令牌,我们将用新值替换资源密码:
PUT : /api/v1/account/password
请求机构:
{ "token":"1234567890", "new":"password" }
响应将是204
无内容响应
服务器已完成请求但不需要返回实体主体,并且可能希望返回更新的元信息.响应可以包括实体标题形式的新的或更新的元信息,如果存在,应该与所请求的变体相关联.
对于想要更改其密码的经过身份验证的用户,PUT
可以在没有电子邮件的情况下立即执行请求(我们更新密码的帐户是服务器已知的).在这种情况下,表单将提交两个字段:
PUT : /api/v1/account/password
请求机构:
{ "old":"password", "new":"password" }
更新:(进一步评论如下)
我会选择这样的东西:
POST /users/:user_id/reset_password
您有一组用户,其中单个用户由{user_name}
.然后,您将指定要操作的操作,在本例中为reset_password
.这就像说"创建(POST
)一个新的reset_password
动作{user_name}
".
上一个答案:
我会选择这样的东西:
PUT /users/:user_id/attributes/password -- The "current password" and the "new password" passed through the body
您将拥有两个集合,一个用户集合以及每个用户的属性集合.用户由:user_id
和指定属性指定password
.该PUT
操作更新集合的已寻址成员.
让我们在一秒钟内获得超级RESTful.为什么不使用DELETE操作来触发重置?有道理,不是吗?毕竟,您实际上是丢弃现有密码而不是另一个密码.
这意味着你会这样做:
DELETE /users/{user_name}/password
现在,两个重要的警告:
HTTP DELETE应该是幂等的(如果你多次执行它就说"没什么大不了的"这个花哨的词).如果您正在执行标准的操作,例如发送"密码重置"电子邮件,那么您将遇到问题.您可以使用布尔值"Is Reset"标记来解决此标记用户/密码的问题.在每次删除时,都会检查此标志; 如果没有设置,则可以重置密码并发送电子邮件.(请注意,拥有此标志也可能有其他用途.)
您不能通过表单使用HTTP DELETE,因此您必须通过POST进行AJAX调用和/或隧道DELETE.
通常,您不希望在初始请求中删除或销毁用户的现有密码,因为这可能是由无权访问该电子邮件的用户(无意或有意)触发的.而是更新用户记录上的重置密码令牌,并将其发送到电子邮件中包含的链接中.单击该链接将确认用户收到了令牌并希望更新其密码.理想情况下,这也是时间敏感的.
在这种情况下,RESTful操作将是POST:在PasswordResets控制器上触发创建操作.操作本身会更新令牌并发送电子邮件.
我实际上是在寻找一个答案,而不是提供一个答案 - 但是在REST上下文中,"reset_password"听起来不对,因为它是动词,而不是名词.即使你说你正在做一个"重置动作"名词 - 使用这个理由,所有动词都是名词.
此外,搜索相同答案的人可能没有想到您可以通过安全上下文获取用户名,而不必通过网址或正文发送它,这让我感到紧张.
我认为更好的主意是:
DELETE /api/v1/account/password - To reset the current password (in case user forget the password) POST /api/v1/account/password - To create new password (if user has reset the password) PUT /api/v1/account/{userId}/password - To update the password (if user knows is old password and new password)
关于提供数据:
重置当前密码
电子邮件应该是正文.
创建新密码(重置后)
新密码,激活码和emailID应该在正文中给出.
更新密码(对于loggedIn用户)
旧密码,新密码应在正文中提及.
Params中的UserId.
头文件中的验证令牌.