Password RESTful reset

What is the proper way to structure a RESTful resource to reset a password?

This resource is intended for password reset for those who have lost or forgotten their password. This will invalidate the old password and email them the password.

Two options that I have:

POST /reset_password/{user_name} 

or...

 POST /reset_password -Username passed through request body 

I am sure the request should be POST. I'm less sure I chose the right name. And I'm not sure if the username should be passed through the url or request body.

+83
rest password-recovery
Jun 19 '10 at 21:06
source share
9 answers

UPDATE: (see below for more details)

I would go for something like this:

 POST /users/:user_id/reset_password 

You have a collection of users where one user is specified {user_name} . Then you specify the action to work, which in this case is reset_password . It's like saying "Create ( POST ) a new reset_password action for {user_name} ".




Previous answer:

I would go for something like this:

 PUT /users/:user_id/attributes/password -- The "current password" and the "new password" passed through the body 

You will have two collections, a collection of users and a collection of attributes for each user. The user is specified :user_id , and the attribute is specified by password . The PUT operation updates the address element of the collection.

+47
Jun 19 '10 at 21:11
source share

Unauthenticated users

We make a PUT request to the api/v1/account/password endpoint and request a parameter with the corresponding email address to determine the account for which the user wants to reset (update) the password:

 PUT : /api/v1/account/password?email={email@example.com} 

Note. As @DougDomeny noted in his comment, sending an email as a query string in a URL is a security risk. GET parameters are not displayed when using https (and you should always use the correct https connection for such requests), but there are other security risks. You can read more on this topic in this blog here .

Passing an email in the body of the request would be a safer alternative to passing it as a GET parameter:

 PUT : /api/v1/account/password 

Request body:

 { "email": "email@example.com" } 

The answer has 202 accepted values, meaning:

The request was accepted for processing, but the processing was not completed. The request may or may not ultimately be processed, as it may be rejected when the processing actually takes place. There is no way to resend the status code from an asynchronous operation such as this.

The user will receive an email at email@example.com and the processing of the update request depends on the actions taken by the link from the email.

 https://example.com/password-reset?token=1234567890 

Opening a link from this email will result in a password form for resetting in the external interface application, which uses a password token to reset from the link as input for a hidden input field (the token is part of the link as a query string). Another input field allows the user to set a new password. The second input to confirm the new password will be used for verification on the external interface (to prevent typos).

Note. It can also be mentioned in the letter that if the user has not initialized the password reset, he / she can ignore the email and continue to use the application in normal mode with his current password.

When a form is submitted with a new password and token as input, a password reset process occurs. The form data will be sent again with a PUT request, but this time with a token, and we will replace the resource password with a new value:

 PUT : /api/v1/account/password 

Request body:

 { "token":"1234567890", "new":"password" } 

Answer will be 204 no answer

The server has completed the request, but it does not need to return the body of the object, and it may want to return updated meta-information. The answer MAY include new or updated meta-information in the form of object headers, which, if present, MUST be associated with the requested option.

Authenticated Users

For authenticated users who want to change their password, the PUT request can be executed immediately without email (the account for which we update the password is known to the server). In this case, two fields will be sent to the form:

 PUT : /api/v1/account/password 

Request body:

 { "old":"password", "new":"password" } 
+53
Oct 28 '15 at 11:13
source share

Let me get uber-RESTful for a second. Why not use the DELETE action for the password to trigger reset? It makes sense, right? In the end, you actually discard the existing password in favor of another.

This means that you would do:

 DELETE /users/{user_name}/password 

Now two big caveats:

  • HTTP DELETE should be idempotent (a fancy word for the word "it doesn't matter if you do this several times"). If you do standard things, such as sending a "Password Reset," you will run into problems. You can bypass this user mark / password using the "Is Reset" logical icon. Each time you delete, you check this flag; if it is not installed, you can reset to enter the password and send your letter. (Note that the presence of this flag may have other uses.)

  • You cannot use HTTP DELETE through the form , so you have to make an AJAX call and / or tunnel DELETE via POST.

+16
Jun 19 '10 at 21:34
source share

Often you do not want to delete or destroy an existing user password at the initial request, as this can be caused (unintentionally or intentionally) by a user who does not have access to email. Instead, update the reset token in the user record and send it via the link included in the email. By clicking on the link, you confirm that the user received the token and wanted to update their password. Ideally, it will also be time sensitive.

The RESTful action in this case will be POST: running the create action on the PasswordResets controller. The action itself will update the token and send an email.

+11
Jan 28 '13 at 20:59
source share

I'm really looking for an answer, not a meaning, to provide one, but "reset_password" doesn't sound right to me in the context of REST because it is a verb, not a noun. Even if you say that you use the noun "reset action" using this excuse, all verbs are nouns.

In addition, someone was not able to find the same answer that you can get the username through the security context and not send it to the URL or body in general, which makes me nervous.

+8
Jan 6 '14 at 20:24
source share

I think the best idea:

 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) 

Regarding data feed:

  • reset current password

    • Email should be indicated in the body.
  • To create a new password (after reset)

    • the new password, activation code and email address must be indicated in the body.
  • To update the password (for user loggedIn)

    • old password, the new password must be specified in the body.
    • UserId in Params.
    • Auth Token in headers.
+6
Nov 24 '17 at 14:25
source share

There are several considerations:

Password reset is not idempotent

Changing the password affects the data used as credentials for its execution, which may invalidate future attempts if the request is simply repeated verbatim while the stored credentials have changed. For example, if a temporary reset token is used to allow a change, as is usually the case with a forgotten password, this token must expire when the password is successfully changed, which again negates further attempts to replicate the request. So the RESTful approach to changing the password seems to be better for POST than for PUT .

URLs with placeholder IDs are not RESTful

A resource that is specified as /password-reset/{user_id} implies that the actual URL pointing to the resource must be created with out-of-band information (that is, we must have prior knowledge of user_id ), and not obtained through discovery. In addition, it is assumed that we will have access to this information at the time of the request, which in many situations will not take place.

The identifier or email in the data upload is probably redundant

Although this does not apply to REST and may have some special purpose, it is often not necessary to provide an identifier or email address to reset a password. Think about it, why did you specify the email address as part of the data for the request that needs to be authenticated, anyway? If the user simply changes his password, he needs to authenticate (through the username: password, email address: password or access token provided through the headers). Therefore, we have access to their account from this step. If they forgot their password, they would be provided with a temporary reset token (via email), which they could use specifically as credentials to make the change. And in this case, authentication with tokens should be enough to identify their account.

Given all of the above, I believe that this is the correct RESTful password change scheme:

User knows their password:

 Method: POST url: /v1/account/password Auth (via headers): joe@example.com:my 0ld pa55wOrd data load: {"password": "This 1s My very New Passw0rd"} 

User does not know his password (password is reset by e-mail):

 Method: POST url: /v1/account/password Access Token (via headers): pwd_rst_token_b3xSw4hR8nKWE1d4iE2s7JawT8bCMsT1EvUQ94aI data load: {"password": "This 1s My very New Passw0rd"} 
+3
Jun 23 '18 at 13:11
source share

I would not have what changes the password and sends them a new one if you decide to use the / users / {id} / password method and stick to your idea that the request is its own resource. i.e. / user-password-request / is a resource and is used by PUT, user information must be in the body. I would not change the password, though, Id sent an email to the user, which contains a link to a page containing request_guid, which can be sent along with the request POST / user / {id} / password /? Request_guid = xxxxx

This will change the password, and it will not allow someone to direct the user by requesting a password change.

Plus, the original PUT may fail if there is an outstanding request.

+2
Sep 03 '14 at 2:51
source share

We update the registered user password PUT / v1 / users / password - we identify the user ID using the AccessToken.

User ID exchange is not secure. The Restful API must identify the user using the AccessToken obtained in the HTTP header.

Spring boot example

 @putMapping(value="/v1/users/password") public ResponseEntity<String> updatePassword(@RequestHeader(value="Authorization") String token){ /* find User Using token */ /* Update Password*? /* Return 200 */ } 
0
Feb 28 '18 at 15:38
source share



All Articles