Appropriate RESTful Handling of Password Reset and Email Verification

I really like consistency and patterns. I may be a little OCD but I think following patterns makes code easier to develop and maintain. I also like to have a good pattern to follow when creating APIs. Have you ever used an API where one endpoint it returns the content at the root of the JSON object but the other did it in a sub-object called ‘data’ and another API returned HTML? I have and I hate it. A lot of these issues can be resolved by following a JSON Style guide. Here is a link to Google’s Style Guide. I like consistency with my API endpoints in addition to the response data.

I don’t purport to be an expert on REST but I do feel like I have a good grasp. If any of you know more official ways to follow the REST specification please let me know. The following is the best way I know to follow the appropriate RESTful protocols.

Brief Overview of REST

So here’s a brief overview of how I understand REST. Every endpoint in REST represents a data model and there are five actions you can perform: index, view, create, update, delete. In the following example we will use ‘user’ as our endpoint.

Index

GET /user

For this endpoint we make a GET request on the User endpoint. It will return a list of all of the users. Normally it doesn’t return all of the details for the users but it can.

View

GET /user/{id}

For this endpoint we make a GET request on the User endpoint but we also add the id of the user we want to view. It will return all of the details for a user.

Create

POST /user

This endpoint is a POST instead of a GET request and it will create a new user.

Update

PUT /user/{id}

This endpoint will update a user’s data. There are two methods for updating a data model, PUT and PATCH. I don’t know how many APIs actually differentiate between PUT and PATCH but I’ll explain the difference. PUT is a replace. It will completely replace the user object with the one you supplied. So if the new data you supplied doesn’t have an email address then the saved data object after the request will also not have an email address. PATCH is different where it only changes the fields you supply. I think most of the time you really want PATCH instead of PUT but most of the time APIs implement PUT the same way as PATCH.

Delete

DELETE /user/{id}

This endpoint obviously will delete an individual user.

Not so black and white?

These REST API endpoints are simple and easy to understand in theory but in practice there are some issues. How can you login a user? Most of the time on websites there is a URL for /user/login but that would break with the pattern. See my solution here.

So here’s the purpose of this post. How do you handle Reset Password and Verify Email?

Reset Password

So to figure out how to handle reset password I thought about what is actually happening when you reset your password. Basically you are just editing the user. The only difference is you are granting permission to only edit the password to whomever has access to the email account. So how can we do that? The answer is creating a special session token that only has access to change the password for a specific user. This token would be one time use, maybe expire after a day, maybe each user can only have one of these active at a time. You’ll have to figure out the details for your own system. So here are the calls that would need to be made:


POST /session

{
"user_id": 1,
"type": "reset-password"
}

// A session token is emailed to the user

PUT /user/1
--user SESSION_TOKEN_RECEIVED_IN_EMAIL

{
"password": "myNewPassword!"
}

Verify email

This is very similar to the reset password above. You create a special token that allows you to change your user’s status. A couple things to note about this is, a user shouldn’t be able to change their status to verified with a general session token, only one of these tokens. With one of these tokens you can only change a status from “unverified” to “verified”. You don’t want people being able to change their status from “banned” to “verified”


POST /session

{
"user_id": 1,
"type": "verify-email"
}

// A session token is emailed to the user

PUT /user/1
--user SESSION_TOKEN_RECEIVED_IN_EMAIL

{
"status": "verified"
}

I've always worked as an innovative programmer. My insights and creative thinking result in superior products and customer satisfaction. Working full time as a senior web architect I've used lots of exciting technologies (i.e., Ember, Backbone, Handlebars, etc) and developed a lot of exciting sites. In my spare time I hope to develop even more exciting and new technologies. I've been programming professionally for 9 years in everything from desktop applications to web applications to mobile applications.

Posted in Wisdom

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

About the Author

  • Chris LondonSenior Web ArchitectPartners In Leadership

    I've always worked as an innovative programmer. My insights and creative thinking result in superior products and customer satisfaction. Working full time as a senior web architect I've used lots of exciting technologies (i.e., Ember, Backbone, Handlebars, etc) and developed a lot of exciting sites. In my spare time I hope to develop even more exciting and new technologies. I've been programming professionally for 9 years in everything from desktop applications to web applications to mobile applications.

    Web: https://plus.google.com/116403409191372324375