Section 4.2 of the draft OAuth 2.0 protocol indicates that an authorization server can return both an access_token
(which is used to authenticate oneself with a
Assume you make the access_token
last very long, and don't have refresh_token
, so in one day, hacker get this access_token
and he can access all protected resources!
But if you have refresh_token
, the access_token
's live time is short, so the hacker is hard to hack your access_token
because it will be invalid after short period of time.
Access_token
can only be retrieved back by using not only refresh_token
but also by client_id
and client_secret
, which hacker doesn't have.
Why not just make the access_token last as long as the refresh_token and not have a refresh_token?
In addition to great answers other people have provided, there is another reason why we would use refresh tokens and it's to do with claims.
Each token contains claims which can include anything from the user's name, their roles, or the provider which created the claim. As a token is refreshed, these claims are updated.
If we refresh the tokens more often, we are obviously putting more strain on our identity services; however, we are getting more accurate and up-to-date claims.
This answer is from Justin Richer via the OAuth 2 standard body email list. This is posted with his permission.
The lifetime of a refresh token is up to the (AS) authorization server — they can expire, be revoked, etc. The difference between a refresh token and an access token is the audience: the refresh token only goes back to the authorization server, the access token goes to the (RS) resource server.
Also, just getting an access token doesn’t mean the user’s logged in. In fact, the user might not even be there anymore, which is actually the intended use case of the refresh token. Refreshing the access token will give you access to an API on the user’s behalf, it will not tell you if the user’s there.
OpenID Connect doesn’t just give you user information from an access token, it also gives you an ID token. This is a separate piece of data that’s directed at the client itself, not the AS or the RS. In OIDC, you should only consider someone actually “logged in” by the protocol if you can get a fresh ID token. Refreshing it is not likely to be enough.
For more information please read http://oauth.net/articles/authentication/
The idea of refresh tokens is that if an access token is compromised, because it is short-lived, the attacker has a limited window in which to abuse it.
Refresh tokens, if compromised, are useless because the attacker requires the client id and secret in addition to the refresh token in order to gain an access token.
Having said that, because every call to both the authorization server and the resource server is done over SSL - including the original client id and secret when they request the access/refresh tokens - I am unsure as to how the access token is any more "compromisable" than the long-lived refresh token and clientid/secret combination.
This of course is different to implementations where you don't control both the authorization and resource servers.
Here is a good thread talking about uses of refresh tokens: OAuth Archives.
A quote from the above, talking about the security purposes of the refresh token:
Refresh tokens... mitigates the risk of a long-lived access_token leaking (query param in a log file on an insecure resource server, beta or poorly coded resource server app, JS SDK client on a non https site that puts the access_token in a cookie, etc)
To clear up some confusion you have to understand the roles of the client secret and the user password, which are very different.
The client is an app/website/program/..., backed by a server, that wants to authenticate a user by using a third-party authentication service. The client secret is a (random) string that is known to both this client and the authentication server. Using this secret the client can identify itself with the authentication server, receiving authorization to request access tokens.
To get the initial access token and refresh token, what is required is:
To get a refreshed access token however the client uses the following information:
This clearly shows the difference: when refreshing, the client receives authorization to refresh access tokens by using its client secret, and can thus re-authenticate the user using the refresh token instead of the user ID + password. This effectively prevents the user from having to re-enter his/her password.
This also shows that losing a refresh token is no problem because the client ID and secret are not known. It also shows that keeping the client ID and client secret secret is vital.
This answer has been put together by the help of two senior devs (John Brayton and David Jennes).
The main reason to use a refresh token is to reduce the attack surface.
Let's suppose there is no refresh key and let’s go through this example:
A building has 80 doors. All doors are opened with the same key. The key changes every 30 minutes. At the end of the 30 minutes I have to give the old key to the keymaker and get a new key.
If I’m the hacker and get your key, then at the end of the 30 minutes, I’ll courier that to the keymaker and get a new key. I’ll be able to continuously open all doors regardless of the key changing.
Question: During the 30 minutes, how many hacking opportunities did I have against the key? I had 80 hacking opportunities, each time you used the key (think of this as making a network request and passing the access token to identify yourself). So that’s 80X attack surface.
Now let’s go through the same example but this time let’s assume there’s a refresh key.
A building has 80 doors. All doors are opened with the same key. The key changes every 30 minutes. To get a new key, I can’t pass the old access token. I must only pass the refresh key.
If I’m the hacker and get your key, I can use it for 30 minutes, but at the end of the 30 minutes sending it to the keymaker has no value. If I do, then the keymaker would just say "This token is expired. You need to refresh the token." To be able to extend my hack I would have to hack the courier to the keymaker. The courier has a distinct key (think of this as a refresh token).
Question: During the 30 minutes, how many hacking opportunities did I have against the refresh key? 80? No. I only had 1 hacking opportunity. During the time the courier communicates with the keymaker. So that’s 1X attack surface. I did have 80 hacking opportunities against the key, but they are no good after 30 minutes.
A server would verify an access token based on credentials and signing of (typically) a JWT.
An access token leaking is bad, but once it expires it is no longer useful to an attacker. A refresh token leaking is far worse, but presumably it is less likely. (I think there is room to question whether the likelihood of a refresh token leaking is much lower than that of an access token leaking, but that’s the idea.)
Point is that the access token is added to every request you make, whereas a refresh token is only used during the refresh flow So less chance of a MITM seeing the token
Frequency helps an attacker. Heartbleed-like potential security flaws in SSL, potential security flaws in the client, and potential security flaws in the server all make leaking possible.
In addition, if the authorization server is separate from the application server processing other client requests then that application server will never see refresh tokens. It will only see access tokens that will not live for much longer.
Compartmentalization is good for security.
Last but not least see this awesome answer
What refresh token is NOT about?
The ability to update/revoke access level through refresh tokens is a byproduct of choosing to use refresh tokens, otherwise a standalone access token could be revoked or have its access level modified when it expires and users gets a new token