Up until today OAuth2 was always very opaque to me. Sure, I was using short-lived token to e.g. make API requests but I never tried to understand the mechanism itself. And actually it’s not that complicated from a conceptual point of view.
The first thing to understand is that there are two kinds of tokens: A refresh token and a bearer token. The bearer token is the one that I usually was dealing with. Here’s a breakdown of the two:
Bearer Token:
- short lived (usually not more than a few hours)
- its purpose is to make the actual API requests, therefore it’s potentially used hundreds or thousand times during its lifetime
Refresh Token:
- long lived (usually multiple days)
- its purpose is to request a new bearer token (usually from a dedicated endpoint, e.g. /oauth/token). Therefore it’s only rarely used (i.e. whenever the bearer token expires, which not more than once per hour)
Here’s a simple flow of the mechanism:
┌─────────────────┐ Exchange for ┌──────────────────┐
│ Refresh Token │ ──────────────────→ │ Bearer Token │
│ (Long-lived) │ new access │ (Short-lived) │
│ 90 days │ token │ 1 hour │
└─────────────────┘ └──────────────────┘
│
│ Used for
▼
┌──────────────────┐
│ File Upload │
│ API Calls │
│ Authentication │
└──────────────────┘
At first glance this mechanism seems over-engineered. Why not simply use a single, long-lived token to the API calls? The answer for this is security. If a service does thousands of API requests, the token gets transmitted for each and every request (at least for REST). Thus, the chances of compromising the token are rather high. But since in OAuth2 the token doing actual API requests is only short-lived, the problem is not that big. Because we know, if the token gets improperly used, it will expire soon anyway - the damage is therefore much smaller in comparison to a mechanism where we would have used a single long-lived token. The refresh token obviously also gets transmitted over the internet and is generally exposed to the danger of interception. However, since it’s not so often transmitted, it’s a smaller risk.
Refresh tokens can be revoked centrally by the issuer, so if it’s known that a refresh token is in the wrong hands, it can be made unusable.
Finally, I was also confused by the difference of bearer tokens and JWT tokens. This is actually also quite simple (at least on a high level): A bearer token is a method of token usage. Everyone presenting a valid bearer token is allowed to access a resource - no further questions asked. A JWT token is a token format. It usually encodes the token as a JSON object along with additional information like user info or permissions. This means a bearer token can be a JWT (or in other words: A JWT can be used as a bearer token). However, bearer token can be anything. Example for a JWT Bearer Token: eyJhblol… Example for a generic Bearer Token: bearertoken1234