Facebook OAuth 2.0 "code" and "token"

Let us take a simple example to differentiate authentication code vs access token.

You as a user want to try a new Facebook app called Highjack. So you click on the application and the Highjack app asks you to log into your Facebook account. When you are done, Facebook generates an authentication code for you.

This code is then passed to the Highjack server which uses its own FB client id, FB secret and your authentication code to get an access token.

In the above example the authentication code is confirming you as a user is a valid FB user. But the second steps says "you as a FB user is giving access to the Highjack app for certain resources".

If the Highjack app wanted implicit grant (i.e direct access token), then the access token would be visible to you also since it is being exchanged with the browser. This means you can now call all Facebook APIs on behalf of Highjack using the access token. (You can only use the access token to get your personal information but Facebook has no way of knowing who is calling their APIs.)

Since we have 2 parties (You and Highjack) authenticating with Facebook we have this 2 fold mechanism.


Borrowed shamelessly from Salesforce Documentation:

Authorization Code

An authorization code is a short-lived token representing the user's access grant, created by the authorization server and passed to the client application via the browser. The client application sends the authorization code to the authorization server to obtain an access token and, optionally, a refresh token.

Access Token The access token is used by the client to make authenticated requests on behalf of the end user. It has a longer lifetime than the authorization code, typically on the order of minutes or hours. When the access token expires, attempts to use it will fail, and a new access token must be obtained via a refresh token.


From the OAuth 2.0 Spec:

The authorization code provides a few important security benefits such as the ability to authenticate the client, and the transmission of the access token directly to the client without passing it through the resource owner's user-agent, potentially exposing it to others, including the resource owner.

So, basically - the main reason is to limit the # of actors getting the access token.

"token" response is intended primarily for clients that live in the browser (e.g.: JavaScript client).


If you look at the flow of Authorization Code OAuth type, yes, there are actuary two steps:

  1. <user_session_id, client_id> => authorization_code
  2. <client_id, redirect_uri, authorization_code, client_secret> => access_token, refresh_token

In step1: the user tells the OAuth Server that "I want to auth this client (client_id) to access my resource. Here is my authentication (user_session_id or what else)"

In step2: the client (client_id) tells the OAuth server that "I've got the user the authorization (authorization_code), please give me an access token for later access. And this is my authentication (client_id & client_secret)"

You see, if we omit step 2, then there is no guarantee for client authentication. Any client can invoke step1 with a different client_id and get an access token for that client_id instead of its own. That's why we need step2.

If you really want to combine step1 and step2, you can do something like this:

<client_id, redirect_uri, client_secret> => access_token, refresh_token

We use this approach in our Open API Platform, and we haven't find any security problem yet.

BTW, there is actually an Implicit Grant type, that is:

<client_id, redirect_uri> => access_token, refresh_token

It is generally applicable to client only application which have no server backend. In that case, the OAuth server must ensure that the redirect URI belongs to that client (same with the register redirect_uri, for example).


The mix-up came because the user on behalf of himself and not the client app authenticate against the authorization server (i.e. facebook). Its much simple to secure the client app (with https) then the user-agent (browser).

Here is the original formulation from IETF-oauth (https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-threatmodel-08#section-3.4):

3.4. Authorization Code

An authorization code represents the intermediate result of a successful end-user authorization process and is used by the client to obtain access and refresh token. Authorization codes are sent to the client's redirection URI instead of tokens for two purposes.

  1. Browser-based flows expose protocol parameters to potential attackers via URI query parameters (HTTP referrer), the browser cache, or log file entries and could be replayed. In order to reduce this threat, short-lived authorization codes are passed instead of tokens and exchanged for tokens over a more secure direct connection between client and authorization server.

  2. It is much simpler to authenticate clients during the direct request between client and authorization server than in the context of the indirect authorization request. The latter would require digital signatures.