When someone connects with an app using Facebook Login, the app will be able to obtain an access token which provides temporary, secure access to Facebook APIs.
An access token is an opaque string that identifies a user, app, or page and can be used by the app to make graph API calls. Access tokens are obtained via a number of methods, each of which are covered later in this document. The token includes information about when the token will expire and which app generated the token. Because of privacy checks, the majority of API calls on Facebook need to include an access token. There are different types of access tokens to support different use cases:
User Access Token – The user token is the most commonly used type of token. This kind of access token is needed any time the app calls an API to read, modify or write a specific person's Facebook data on their behalf. User access tokens are generally obtained via a login dialog and require a person to permit your app to obtain one.
App Access Token – This kind of access token is needed to modify and read the app settings. It can also be used to publish Open Graph actions. It is generated using a pre-agreed secret between the app and Facebook and is then used during calls that change app-wide settings. You obtain an app access token via a server-to-server call.
Page Access Token – These access tokens are similar to user access tokens, except that they provide permission to APIs that read, write or modify the data belonging to a Facebook Page. To obtain a page access token you need to start by obtaining a user access token and asking for the manage_pages
permission. Once you have the user access token you then get the page access token via the Graph API.
Client Token - The client token is an identifier that you can embed into native mobile binaries or desktop apps to identify your app. The client token isn't meant to be a secret identifier because it's embedded in applications. The client token is used to access app-level APIs, but only a very limited subset. The client token is found in your app's dashboard. Since the client token is used rarely, we won't talk about it in this document. Instead it's covered in any API documentation that uses the client token.
Although each platform generates access tokens through different APIs, all platforms follow the basic strategy to get a user token:
Different platforms have different methods to kick off this process and include functionality to manage access tokens on behalf of the developer and the person granting permissions:
FB.getAuthResponse
which will include an accessToken
property within the response.FBSession
andcom.facebook.Session
classes, respectively. You can learn more about starting the login process in our guides for iOS and Android. You can retrieve the access token by inspecting FBSession.accessTokenData
orSession.getAccessToken.User access tokens come in two forms: short-lived tokens and long-lived tokens. Short-lived tokens usually have a lifetime of about an hour or two, while long-lived tokens usually have a lifetime of about 60 days. You should not depend on these lifetimes remaining the same - the lifetime may change without warning or expire early. See more under handling errors.
Access tokens generated via web login are short-lived tokens, but you can upgrade them to long-lived tokens. Converting short-lived tokens to long-lived tokens is covered later in this document under Expiration and Extending Tokens.
Mobile apps that use Facebook's mobile SDKs get long-lived tokens.
One important aspect to understand about access token is that they are portable. Once you have an access token you can use it to make calls from a mobile client, a web browser, or from your server to Facebook's servers. If a token is obtained on a client, you can ship that token back to your server and use it in server-to-server calls. If a token is obtained via a server call, you can also ship that token down to a client and then make the calls from the client.
This portability comes with significant security and architecture implications which must be considered when designing how you want to handle access tokens, authentication and your app's flow. These topics are covered later in this document.
App access tokens are used to make requests to Facebook APIs on behalf of an app rather than a user. This can be used to modify the parameters of your app, create and manage test users, or read your application's insights. App access tokens can also be used to publish content to Facebook on behalf of a person who has granted an open graph publishing permission to your application.
Note that app tokens are considered insecure if your app is set to Native/Desktop
in the Advanced settings of your App Dashboard and therefore will not work with API calls. This is because we assume that native or desktop apps will have the app secret embedded somewhere (and therefore the app token generated using that secret is not secure).
To generate an app access token, you need to make a Graph API call:
GET /oauth/access_token?
client_id={app-id}
&client_secret={app-secret}
&grant_type=client_credentials
This call will return an app access token which can be used in place of a user access token to make API calls as noted above. Again, for security, app access token should never be hard-coded into client-side code, doing so would give everyone who loaded your webpage or decompiled your app full access to your app secret, and therefore the ability to modify your app. This implies that most of the time, you will be using app access tokens only in server to server calls.
Note that because this request uses your app secret, it must never be made in client-side code or in an app binary that could be decompiled. It is important that your app secret is never shared with anyone. Therefore, this API call should only be made using server-side code.
There is another method to make calls to the Graph API that doesn't require using a generated app token. You can just pass your app id and app secret as the access_token
parameter when you make a call:
https://graph.facebook.com/endpoint?key=value&access_token=app_id|app_secret
The choice to use a generated access token vs. this method depends on where you hide your app secret.
Page access tokens are used in Graph API calls to manage Facebook Pages. To generate a page access token, an admin of the page must grant an extended permission called manage_pages
. Once this permission has been granted, you can retrieve the page access token using the following Graph API request:
GET /{user-id}/accounts
This can be requested with a user access token with the required permissions. This will return a list of pages that person admins with some additional info (such as the page category and the permissions the admin has for that page) as well as the page access token:
{
"data": [
{
"category": "Product/service",
"name": "Sample Page",
"access_token": "{access-token}",
"id": "1234567890",
"perms": [
"ADMINISTER",
"EDIT_PROFILE",
"CREATE_CONTENT",
"MODERATE_CONTENT",
"CREATE_ADS",
"BASIC_ADMIN"
]
},
}
You can use this type of token to make API calls on behalf of a Page. For example, you could post a status update to a Page (rather than on the user's timeline) or read Page Insights data.
Page access tokens are unique to each Page, admin and app.
Page admins have different roles, which is indicated by the perms
array returned as above. The functionality available to them is decided based on the following perms
values:
Value | Description | Roles this Applies To |
---|---|---|
|
Manage admins |
Full Admin |
|
Edit the Page and add apps |
Full Admin, Content Creator |
|
Create posts as the Page |
Full Admin, Content Creator |
|
Respond to and delete comments, send messages as the Page |
Full Admin, Content Creator, Moderator |
|
Create ads and unpublished page posts |
Full Admin, Content Creator, Moderator, Ads Creator |
|
View Insights |
Full Admin, Content Creator, Moderator, Ads Creator, Insights Manager |
As noted above, access tokens are portable. This means that once you obtain a token, you can generally use it from any machine - server, client or otherwise. When you combine web interfaces, mobile clients and servers you can get a mix of different possible configurations. However, these different configurations come with different trade-offs in terms of capabilities and security. We cover some of the more common scenarios here so you can build your app with the right model.
This chart contains a comparison of several different configurations. Details about the configurations covered in this chart are below.
Configuration | Advantages | Disadvantages | Security Notes |
---|---|---|---|
Login happens in a Web Client. API requests happen in a Web Client (short-term token). |
Simple to implement. |
No offline posting, no long-term access, must auth often. |
|
Login happens in a Native Mobile Client or a Web Client with Long Term Token. API requests happen in the Client (with long-term token). |
Auth not required often with long-term token. |
No offline posting. |
|
Login happens in a Web Client. API requests happen in the Web Client (long-term token after code exchange). |
Extra security in certain situations. |
Harder to implement. No offline posting. Shouldn't be used in the usual case. |
This is only useful in very specific situations See thedocs below for more information. |
Login happens in a Native Mobile Client or a Web Client. API requests happen on a Server (with long-term token). |
Offline posting. Takes advantage of security features available with server-based calls. |
Client must call the server to proxy any calls. |
You should use |
Login happens in a Native Mobile Client or Web Client. API requests happen on a Server or in the Client. |
Offline posting. User-driven posting from the client. |
Implementation can be complex. |
You should use |
This is the simplest model where the auth is done on the client all calls also run through the client. There are three possible configurations in this model:
Native client or web client makes API calls with token:
Web client makes API calls after exchanging the short-term token for a long-term token:
Web client makes API calls after code exchange for long-term token (Rarely used):
This is a very common configuration where the auth happens on the client, but the server makes all calls on behalf of the client. The server can use the appsecret_proof
parameter to further enhance security when it makes calls.
This is a hybrid of the above approaches. This is listed here so you can see that it's possible to combine these approaches depending on your use case.
There are different ways to explicitly specify which access token to use with an API call in our SDKs:
access_token
.openFromAccessTokenData
methodSession.open(AccessToken, StatusCallback)
method.Security Note: in all above cases, the code can be directly viewed, either by reading the HTML source or by decompiling an app binary. Therefore, your app should never have an access token hard-coded into it. Instead, calls could be made directly with the response from the access token generation request.
Facebook's official SDKs manage the lifetime of tokens for you. When using iOS, Android or our JavaScript SDK, the SDK will handle making sure that tokens are refreshed before they expire.
Native mobile applications using Facebook's SDKs will get long-lived access tokens, good for about 60 days. These tokens will be refreshed once per day when the person using your app makes a request to Facebook's servers. If no requests are made, the token will expire after about 60 days and the person will have to go through the login flow again to get a new token.
Access tokens on the web often have a lifetime of about two hours, but will automatically be refreshed when required. If you want to use access tokens for longer-lived web apps, especially server side, you need to generate a long-lived token. A long-lived token generally lasts about 60 days. This is what the process for generating a long-lived token looks like:
Here are the steps that you need to take to generate a long-lived token:
Start with a short-lived token generated on a client and ship it back to your server.
Use the user token, your app ID and app secret to make the following call from your server to Facebook's servers:
GET /oauth/access_token?
grant_type=fb_exchange_token&
client_id={app-id}&
client_secret={app-secret}&
fb_exchange_token={short-lived-token}
Make this call from your server, not a client. The app secret is included in this API call, so you should never actually make the request client-side. Instead implement server-side code that makes the request, then pass the response containing the long-lived token back to your client-side code. This will be a different string than the original token, so if you're storing these tokens, replace the old one.
An important note: Apps are unable to exchange an expired short-lived token for a long-lived token. The flow above only works with short-lived tokens that are still valid. Once they expire, your app must send the user through the login flow again to generate a new short-lived token.
Even the long-lived access token will eventually expire. At any point, you can generate a new long-lived token by sending the person back to the login flow used by your web app - note that the person will not actually need to login again, they have already authorized your app, so they will immediately redirect back to your app from the login flow with a refreshed token - how this appears to the person will vary based on the type of login flow that you are using, for example if you are using the JavaScript SDK, this will take place in the background, if you are using a server-side flow, the browser will quickly redirect to the Login Dialog and then automatically and immediately back to your app again.
After doing the above you will obtain a new short-lived token and then you need to perform the same exchange for a long-lived token as above.
In some cases, this newer long-lived token might be identical to the previous one, but we can't guarantee it and your app shouldn't depend upon it.
With the iOS and Android SDKs, long-lived tokens are used by default and should automatically be refreshed.
Apps can retrieve a Page access token from Page admin users when they authenticate with the manage_pages permission. If the user access token used to retrieve this Page access token is short-lived, the Page access token will also be short-lived.
To get a longer-lived Page access token, exchange the User access token for a long-lived one, as above, and then request the Page token. The resulting Page access token will not have any expiry time.
You should, in general, not use the same long-lived tokens on more than one web client (i.e. if the person logs in from more than one computer.) Instead you should use the long-lived tokens on your server to generate a code and then use that to get a long-lived token on the client. Please see below for information Generating long-lived tokens from server-side long-lived tokens.
Facebook has an advanced option for obtaining long-lived access tokens for apps that:
If your app is set up like this it should use the process described here to obtain an access token from each client to avoid triggering Facebook's automated spam systems. The end result will be that each client will have its own long-lived access token.
At a high level, this is how you can obtain a long-lived token from the client:
This is a diagram of the flow:
Using a long-lived user access token, make a call to the following endpoint:
https://graph.facebook.com/oauth/client_code?access_token=...&client_secret=...&redirect_uri= ...
The call requires the following arguments:
Argument | Required | Description |
---|---|---|
|
Yes |
Long-lived user access token. |
|
Yes |
The app's app secret. |
|
Yes |
The redirect URI must be set to the exact value in the app's configuration. |
The response will look something like:
{"code": "...."}
Once you've retrieved the code from Facebook's server you then need to ship it to the client via a secure channel. Once that's done, you need to make a request from the client to this endpoint:
https://graph.facebook.com/oauth/authorize?code=...&client_id=...&redirect_uri=...&machine_id= ...
The call requires the following arguments:
Argument | Required | Description |
---|---|---|
|
Yes |
The App ID. |
|
Yes |
The code returned from Facebook's server. |
|
Yes |
The redirect URI must be set to the exact value in the app's configuration. |
|
No |
An important per-client (not per-user) value that tracks clients and is used for security. If you're previously made calls to get a code and been provided a |
The response will look like:
{"access_token":"...", "expires_in":..., "machine_id":"..."}
Returned values are:
Value | Description |
---|---|
|
A new long-lived access token that you can use for Graph API calls. |
|
The number of seconds until this access token expires. |
|
The machine_id for this client. Please store this for future calls to generate a new access token from a code. This helps identify this client and is used to prevent spam. |
When working with an access token, you may need to check what information is associated with it, such as its user or expiry. To get this information you can use our debug tool, or you can use the API endpoint.
To use the API, you can issue a Graph API request:
GET /debug_token?
input_token={input-token}&
access_token={access-token}
input_token
: the access token you want to get information aboutaccess_token
: your app access token or a valid user access token from a developer of the appThe response of the API call is a JSON array containing a map of fields. For example:
{
"data": {
"app_id": 000000000000000,
"application": "Social Cafe",
"expires_at": 1352419328,
"is_valid": true,
"issued_at": 1347235328,
"scopes": [
"email",
"publish_actions"
],
"user_id": 1207059
}
}
Note that the issued_at
field is not returned for short-lived access tokens.
Facebook doesn't notify you that a previously issued access token has become invalid. Unless you have persisted theexpiry
time passed to your App along with the access token, your app may only learn that a given token has become invalid is when you attempt to make a request to the API. Also, in response to certain events that are security-related, access tokens may be invalidated before the expected expiration time.
In most apps, the best way to handle expired tokens is to capture the error messages thrown by the API. In each case, the API will return an HTTP 400 status code, a code and a subcode in a JSON body explaining the nature of the error. (These examples don't include a subcode, but subcodes are described in the error reference.)
Access Token has expired
{
"error": {
"message": "Error validating access token: Session has expired at unix
time SOME_TIME. The current unix time is SOME_TIME.",
"type": "OAuthException",
"code": 190
}
}
Access Token invalidated due to the person logging out or changing their password
{
"error": {
"message": "Error validating access token: The session is invalid
because the user logged out.",
"type": "OAuthException",
"code": 190
}
}
If the access token becomes invalid, the solution is to have the person log in again, at which point you will be able to make API calls on their behalf once more. The login flow your app uses for new people should determine which method you need to adopt.
{
"error": {
"message": "Error validating access token: User USER_ID has
not authorized application APP_ID.",
"type": "OAuthException",
"code": 190
}
}
When someone has de-authorized your app it should treat someone as if they are new to the app.
You can read about more errors in our API Error reference but these three errors are the most common when dealing with access tokens.
API errors in the iOS SDK are typically surfaced through the NSError
instances passed to the callbacks. See the iOS error documentation for more details. For deprecated (2.0) APIs, see FBRequestDelegate
.
API errors in the Android SDK are typically surfaced via the Response
object passed to the Requests
's callback. Specifically you can call response.getError()
to retrieve a FacebookRequestError
instance
Expect that the size of all types of access tokens will change over time as Facebook makes changes to what is stored in them and how they are encoded. You can expect that they will grow and shrink over time. Please use a variable length data type without a specific maximum size to store access tokens.