What is the proper way to structure a RESTful resource for resetting a password?
This resource is meant to be a password resetter for someone who has lost or forgotten their password. It invalidates their old password and e-mails them a password.
The two options that I have are:
POST /reset_password/{user_name}
or...
POST /reset_password
-Username passed through request body
I'm pretty sure the request should be a POST. I'm less confident that I have selected an appropriate name. And I'm not sure if the user_name should be passed through the URL or the request body.
Often you don't want to delete or destroy the user's existing password on the initial request, as this may have been triggered (unintentionally or intentionally) by a user that does not have access to the email. Instead, update a reset password token on the user record and send that in a link included in an email. Clicking on the link would confirm the user received the token and wished to update their password. Ideally, this would be time sensitive as well.
The RESTful action in this case would be a POST: triggering the create action on the PasswordResets controller. The action itself would update the token and send an email.
Let's get uber-RESTful for a second. Why not use the DELETE action for the password to trigger a reset? Makes sense, doesn't it? After all, you're effectively discarding the existing password in favor of another one.
That means you'd do:
Now, two big caveats:
HTTP DELETE is supposed to be idempotent (a fancy word for saying "no big deal if you do it multiple times"). If you're doing the standard stuff like sending out a "Password Reset" email, then you're going to run into problems. You could work around this tagging the user/password with a boolean "Is Reset" flag. On every delete, you check this flag; if it's not set then you can reset the password and send your email. (Note that having this flag might have other uses too.)
You can't use HTTP DELETE through a form, so you'll have to make an AJAX call and/or tunnel the DELETE through the POST.
UPDATE: (further to comment below)
I would go for something like this:
You have a collection of users, where the single user is specified by the
{user_name}
. You would then specify the action to operate on, which in this case isreset_password
. It is like saying "Create (POST
) a newreset_password
action for{user_name}
".Previous answer:
I would go for something like this:
You'd have two collections, a users collection, and an attributes collection for each user. The user is specified by the
:user_id
and the attribute is specified bypassword
. ThePUT
operation updates the addressed member of the collection.