Instead of sending the user’s credentials in each request, a common approach is to use tokens. A token is simply an encoded string originating from the server after a user successfully logs in. That token is used to authenticate the user until it is invalidated, at which point the user must login again for a new token.
How it works
The interesting thing about tokens is that the server doesn’t hold onto them, either in memory or a database, making means that token-based auth stateless. We’ll cover the tradeoffs with stateless auth in a later post.
A token generally consists of three components: a header, a payload, and a signature.
The token header (not an HTTP header) contains information about the type of token being used, as well as how to interpret its signing signature (more on that below).
The payload consists of data related to the user’s auth session. What this data looks like depends on the type of token we’re working with.
So how the heck does your server know how to validate a token is authentic if it doesn’t store it somewhere? That’s where the signature comes in.
A token’s signing signature is generated by an algorithm based on some data provided by the user’s client. The token can only be decoded and validated with a secret value kept safe on the server. So all the server needs is the user’s unique token in each request to handle authentication.
Why you should use it
Similar to server sessions, token-based auth is more secure than basic auth because validated credentials are never passed between the server and client directly. This makes requests are less vulnerable if intercepted.
Because token-based auth is stateless, it is highly portable. Any server or service can validate a token based only on the data in the token itself and its secret. It’s a solid approach when used with cloud architecture or distributed systems where state is much more difficult to manage.
Imagine if you serve different pieces of data from multiple servers*.
Which server is responsible for handling sessions, and how do other servers validate them? This isn’t an issue with tokens, so long as all servers have a reference to the secret.
*Why would you serve your app data from different servers? Stay tuned to Front to Back to find out!
Why you shouldn’t use it
A big downside to token-based auth is that revoking access is difficult.
What if you need to suspend a user’s account? How will our server know the token is bad if it’s validating against a signature we’ve already validated? You can’t simply change the secret since it’s needed for all other validated tokens.
There are a number of solutions here, each one with its own tradeoffs. That’ll be covered another day, but the bottom line is tokens add complexity when you need to revoke access.
With tokens you also need to worry about keeping your secrets … secret. If somehow your secret is leaked, hackers can easily gain access to sensitive user data. Nobody wants that (except for maybe hackers). You’ll need to rotate secrets often enough to minimize risk, but not so often that users have to constantly re-authenticate to use your app.