If you didn’t catch it, in the last article I explained how to know to build and deploy a real mobile app that uses OAuth2 authentication for your private API service.
In this article, I’m going to cover a tightly related topic: how to properly manage your OAuth2 API token lifecycle.
Because things like token expiration and revocation are so paramount to API security, I figured they deserved their own discussion here.
Developers typically ask us this:
“This OAuth2 stuff with JSON Web Tokens sounds good, but how long should I allow my access tokens to exist before expiring them? I don’t want to force my users to re-authenticate every hour. That would suck.”
This is an excellent question. The answer is a bit tricky though. Here are some general rules:
If you’re dealing with any form of sensitive data (money, banking data, etc.), don’t bother storing access tokens on the mobile device at all. When you authenticate the user and get an access token, just keep it in memory. When a users closes your app, your memory will be cleaned up, and the token will be gone. This will force users to log into your app every time they open
it, but that’s a good thing.
For extra security, make sure your tokens themselves expire after a short period of time (eg: 1 hour) — this way, even if an attacker somehow compromises your access token, it’ll still expire fairly quickly.
If you’re building an app that holds sensitive data, that’s not related to money, you’re probably fine forcing tokens to expire somewhere around the range of every month. For instance, if I was building a mobile app that allowed users to take fitness progress photos of themselves to review at a later time, I’d use a 1 month setting.
The above setting is a good idea as it doesn’t annoy users, requiring them to re-input their credentials every time the open the app, but also doesn’t expose them to unnecessary risk. In the worst case scenario above, if a user’s access token is compromised, an attacker might be able to view this person’s progress photos for up to one month.
If you’re building a massive consumer application, like a game or social application, you should probably use a much more liberal expiration time: anywhere from 6 months to 1 year.
For these sorts of applications, there is very little risk storing an access token for a long period of time, as the service contains only low-value content that can’t really hurt a user much if leaked. If a token is compromised, it’s not the end of the world.
This strategy also has the benefit of not annoying users by prompting them to re-authenticate very frequently. For many mass consumer applications, signing in is considered a big pain, so you don’t want to do anything to break down your user experience.
Let’s now talk about token revocation. What do you do if an access token is compromised?
Firstly, let’s discuss the odds of this happening. In general: they are very low. Using the recommended data stores for Android and iOS will greatly reduce the risk of your tokens being compromised, as the operating system provides a lot of built-in protections for storing sensitive data like access tokens.
But, let’s assume for this exercise that a user using your mobile app lost their phone, a saavy hacker grabbed it, broke through the OS-level protections, and was able to extract your API service’s access token.
What do you do?
This is where token revocation comes into play.
It is, in general, a good idea to support token revocation for your API service. What this means is that you should have a way to strategically invalidate tokens after issuing them.
NOTE: Many API services do not support token revocation, and as such, simply rely on token expiration times to handle abuse issues.
Supporting token revocation means you’ll have to go through an extra few steps when building this stuff out:
- You’ll need to store all access tokens (JWTs) that you generate for clients in a database. This way, you can see what tokens you’ve previously assigned, and which ones are valid.
You’ll need to write an API endpoint which accepts an access token (or user credentials) and removes either the specific access token or all access tokens from a user’s account.
For those of you wondering how this works, the official
OAuth2 Revocation Spec actually talks about it in very simple terms. The gist of it is that you write an endpoint like
/revoke that accepts POST requests, with the token or credentials in the body of the request.
The idea is basically this though: once you know that a given access token, or user account has been compromised, you’ll issue the appropriate revocation API request to your private API service. You’ll either revoke:
- The single access token, or
- All access tokens for a given user account.
Make sense? Great!
If you’re planning on writing your own API service like the ones discussed in this article, you’ll want to write as little of the actual security code as possible. Actual implementation details can be quite a bit more complex, depending on your framework and programming langugage.
Stormpath is an API service that stores your user accounts securely, manages API keys, handles OAuth2 flows, and also provides tons of convenience methods / functions for working with user data, doing social login, and a variety of other things.
If you have any questions (this stuff can be confusing), feel free to email us directly — we really don’t mind answering questions! You can, of course, also just leave a comment below. Either way works!