A static, never-changing API key poses a security risk - it's essentially an obsfucated primary key - say for some sort of User. If this API key is ever leaked - for example, in a log file or you accidentally use HTTP - then anyone can act on behalf of you indefinetly until the API key is changed.
JSON Web Tokens to the Rescue
We can use the JSON Web Token standard (make sure to read that link before you continue!) to create limited use API authorization tokens that last for a short period of time (for example, 2 seconds). This gives us plenty of time to make a complete HTTP request, yet causes any previous tokens to become useless.
Say we have some sort of blog API service where a user can make blog posts using an API. With a traditional API key, you might have a
User model with an
Using JWT, you would have an
api_secret field. Unlike the API key method, this secret is never sent between the client and the API.
To make this transaction successful, both the client and the API server need to know the following:
- The User ID
- Some shared secret
The client-side implementation might look something like this:
The API server might have an implementation that looks similar to this. Note some checks (such as checking for the presence of an
Authorization header are ommited)
An Even More Secure Implementation
You can assign an unique one-time use
jti field to your JWT payload. Using some redis magic, you can completely remove the possibility of a replay attack - meaning if your JWT token is compromised, it can never be used again.
This takes some inspiration from the Zendesk JWT implementation.
We can modify the
set_current_user_from_jwt_token from earlier: