By Chris on Code
This tutorial is out of date and no longer maintained.
Token-based authentication is prominent everywhere on the web nowadays. With most web companies using an API, tokens are the best way to handle authentication for multiple users.
There are some very important factors when choosing token-based authentication for your application. The main reasons for tokens are:
Any major API or web application that you’ve come across has most likely used tokens. Applications like Facebook, Twitter, Google+, GitHub, and so many more use tokens.
Let’s take a look at exactly how it works.
Before we can see how token-based authentication works and its benefits, we have to look at the way authentication has been done in the past.
Since the HTTP protocol is stateless, this means that if we authenticate a user with a username and password, then on the next request, our application won’t know who we are. We would have to authenticate again.
The traditional way of having our applications remember who we are is to store the user logged-in information on the server. This can be done in a few different ways on the session, usually in memory or stored on the disk.
As the web, applications, and the rise of the mobile application have come about, this method of authentication has shown problems, especially in scalability.
A few major problems arose with this method of authentication.
With these problems, scalability being the main one, it made sense to try a different approach.
Token-based authentication is stateless. We are not storing any information about our user on the server or in a session.
This concept alone takes care of many of the problems with having to store information on the server.
No session information means your application can scale and add more machines as necessary without worrying about where a user is logged in.
Although this implementation can vary, the gist of it is as follows:
Every single request will require the token. This token should be sent in the HTTP header so that we keep with the idea of stateless HTTP requests. We will also need to set our server to accept requests from all domains using
Access-Control-Allow-Origin: *. What’s interesting about designating
* in the ACAO header is that it does not allow requests to supply credentials like HTTP authentication, client-side SSL certificates, or cookies.
Once we have authenticated with our information and we have our token, we are able to do many things with this token.
We could even create a permission-based token and pass this along to a third-party application (say a new mobile app we want to use), and they will be able to have access to our data – but only the information that we allowed with that specific token.
Tokens are stored on the client-side. Completely stateless and ready to be scaled. Our load balancers are able to pass a user along to any of our servers since there is no state or session information anywhere.
If we were to keep session information on a user that was logged in, this would require us to keep sending that user to the same server that they logged in at (called session affinity).
This brings problems since some users would be forced to the same server and this could bring about a spot of heavy traffic.
Not to worry though! Those problems are gone with tokens since the token itself holds the data for that user.
The token, not a cookie, is sent on every request and since there is no cookie being sent, this helps to prevent CSRF attacks. Even if your specific implementation stores the token within a cookie on the client-side, the cookie is merely a storage mechanism instead of an authentication one. There is no session-based information to manipulate since we don’t have a session!
The token also expires after a set amount of time, so a user will be required to log in once again. This helps us stay secure. There is also the concept of token revocation that allows us to invalidate a specific token and even a group of tokens based on the same authorization grant.
Tokens will allow us to build applications that share permissions with another. For example, we have linked random social accounts to our major ones like Facebook or Twitter.
When we log in to Twitter through a service (let’s say Buffer), we are allowing Buffer to post to our Twitter stream.
By using tokens, this is how we provide selective permissions to third-party applications. We could even build our own API and hand out special permission tokens if our users wanted to give access to their data to another application.
We talked a bit about CORS earlier. When our application and service expands, we will need to be providing access to all sorts of devices and applications (since our app will most definitely become popular!).
Having our API just serve data, we can also make the design choice to serve assets from a CDN. This eliminates the issues that CORS brings up after we set a quick header configuration for our application.
Our data and resources are available to requests from any domain now as long as a user has a valid token.
When creating the token, you have a few options. We’ll be diving more into this topic when we secure an API in a follow-up article, but the standard to use would be JSON Web Tokens.
This handy debugger and library chart shows the support for JSON Web Tokens. You can see that it has a great amount of support across a variety of languages. This means you could actually switch out your authentication mechanism if you choose to do so in the future!
This was just a look at the how and why of token-based authentication. As is always the case in the world of security, there is much more to each topic and it varies per use case. We even dove into some topics on scalability which deserves its own conversation as well.
This was a high-level quick overview, so please feel free to point out anything that was missed or any questions you have on the matter.
In our next article, we’ll be looking at the anatomy of JSON Web Tokens.
Note: Adding ACAO header info and CSRF clarifications (thanks to Emily Stark for the article info)
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.