The link to discussion, provided by Catchdave, has another valid point (original, dead link) made by Dick Hardt, which I believe is worth to be mentioned here in addition to what's been written above:
My recollection of refresh tokens was for security and revocation.
<...>
revocation: if the access token is self contained, authorization can be revoked by not issuing new access tokens. A resource does not need to query the authorization server to see if the access token is valid.This simplifies access token validation and makes it easier to scale and support multiple authorization servers. There is a window of time when an access token is valid, but authorization is revoked.
Indeed, in the situation where Resource Server and Authorization Server is the same entity, and where the connection between user and either of them is (usually) equally secure, there is not much sense to keep refresh token separate from the access token.
Although, as mentioned in the quote, another role of refresh tokens is to ensure the access token can be revoked at any time by the User (via the web-interface in their profiles, for example) while keeping the system scalable at the same time.
Generally, tokens can either be random identifiers pointing to the specific record in the Server's database, or they can contain all information in themselves (certainly, this information have to be signed, with MAC, for example).
How the system with long-lived access tokens should work
The server allows the Client to get access to User's data within a pre-defined set of scopes by issuing a token. As we want to keep the token revocable, we must store in the database the token along with the flag "revoked" being set or unset (otherwise, how would you do that with self-contained token?) Database can contain as much as len(users) x len(registered clients) x len(scopes combination)
records. Every API request then must hit the database. Although it's quite trivial to make queries to such database performing O(1), the single point of failure itself can have negative impact on the scalability and performance of the system.
How the system with long-lived refresh token and short-lived access token should work
Here we issue two keys: random refresh token with the corresponding record in the database, and signed self-contained access token, containing among others the expiration timestamp field.
As the access token is self-contained, we don't have to hit the database at all to check its validity. All we have to do is to decode the token and to validate the signature and the timestamp.
Nonetheless, we still have to keep the database of refresh tokens, but the number of requests to this database is generally defined by the lifespan of the access token (the longer the lifespan, the lower the access rate).
In order to revoke the access of Client from a particular User, we should mark the corresponding refresh token as "revoked" (or remove it completely) and stop issuing new access tokens. It's obvious though that there is a window during which the refresh token has been revoked, but its access token may still be valid.
Tradeoffs
Refresh tokens partially eliminate the SPoF (Single Point of Failure) of Access Token database, yet they have some obvious drawbacks.
The "window". A timeframe between events "user revokes the access" and "access is guaranteed to be revoked".
The complication of the Client logic.
without refresh token
- send API request with access token
- if access token is invalid, fail and ask user to re-authenticate
with refresh token
- send API request with access token
- If access token is invalid, try to update it using refresh token
- if refresh request passes, update the access token and re-send the initial API request
- If refresh request fails, ask user to re-authenticate
I hope this answer does make sense and helps somebody to make more thoughtful decision. I'd like to note also that some well-known OAuth2 providers, including github and foursquare adopt protocol without refresh tokens, and seem happy with that.
Best Answer
Background: I've written client and server stacks for OAuth 1.0a and 2.0.
Both OAuth 1.0a & 2.0 support two-legged authentication, where a server is assured of a user's identity, and three-legged authentication, where a server is assured by a content provider of the user's identity. Three-legged authentication is where authorization requests and access tokens come into play, and it's important to note that OAuth 1 has those, too.
The complex one: three-legged authentication
A main point of the OAuth specs is for a content provider (e.g. Facebook, Twitter, etc.) to assure a server (e.g. a Web app that wishes to talk to the content provider on behalf of the client) that the client has some identity. What three-legged authentication offers is the ability to do that without the client or server ever needing to know the details of that identity (e.g. username and password).
Without (?) getting too deep into the details of OAuth:
The server can now make requests to the content provider on behalf of the user by passing the access token.
Each exchange (client->server, server->content provider) includes validation of a shared secret, but since OAuth 1 can run over an unencrypted connection, each validation cannot pass the secret over the wire.
That's done, as you've noted, with HMAC. The client uses the secret it shares with the server to sign the arguments for its authorization request. The server takes the arguments, signs them itself with the client's key, and is able to see whether it's a legitimate client (in step 1 above).
This signature requires both the client and the server to agree on the order of the arguments (so they're signing exactly the same string), and one of the main complaints about OAuth 1 is that it requires both the server and clients to sort and sign identically. This is fiddly code and either it's right or you get
401 Unauthorized
with little help. This increases the barrier to writing a client.By requiring the authorization request to run over SSL, OAuth 2.0 removes the need for argument sorting and signing altogether. The client passes its secret to the server, which validates it directly.
The same requirements are present in the server->content provider connection, and since that's SSL that removes one barrier to writing a server that accesses OAuth services.
That makes things a lot easier in steps 1, 2, and 5 above.
So at this point our server has a permanent access token which is a username/password equivalent for the user. It can make requests to the content provider on behalf of the user by passing that access token as part of the request (as a query argument, HTTP header, or POST form data).
If the content service is accessed only over SSL, we're done. If it's available via plain HTTP, we'd like to protect that permanent access token in some way. Anyone sniffing the connection would be able to get access to the user's content forever.
The way that's solved in OAuth 2 is with a refresh token. The refresh token becomes the permanent password equivalent, and it's only ever transmitted over SSL. When the server needs access to the content service, it exchanges the refresh token for a short-lived access token. That way all sniffable HTTP accesses are made with a token that will expire. Google is using a 5 minute expiration on their OAuth 2 APIs.
So aside from the refresh tokens, OAuth 2 simplifies all the communications between the client, server, and content provider. And the refresh tokens only exist to provide security when content is being accessed unencrypted.
Two-legged authentication
Sometimes, though, a server just needs to control access to its own content. Two-legged authentication allows the client to authenticate the user directly with the server.
OAuth 2 standardizes some extensions to OAuth 1 that were in wide use. The one I know best was introduced by Twitter as xAuth. You can see it in OAuth 2 as Resource Owner Password Credentials.
Essentially, if you can trust the client with the user's credentials (username and password), they can exchange those directly with the content provider for an access token. This makes OAuth much more useful on mobile apps--with three-legged authentication, you have to embed an HTTP view in order to handle the authorization process with the content server.
With OAuth 1, this was not part of the official standard, and required the same signing procedure as all the other requests.
I just implemented the server side of OAuth 2 with Resource Owner Password Credentials, and from a client's perspective, getting the access token has become simple: request an access token from the server, passing the client id/secret as an HTTP Authorization header and the user's login/password as form data.
Advantage: Simplicity
So from an implementor's perspective, the main advantages I see in OAuth 2 are in reduced complexity. It doesn't require the request signing procedure, which is not exactly difficult but is certainly fiddly. It greatly reduces the work required to act as a client of a service, which is where (in the modern, mobile world) you most want to minimize pain. The reduced complexity on the server->content provider end makes it more scalable in the datacenter.
And it codifies into the standard some extensions to OAuth 1.0a (like xAuth) that are now in wide use.