Facebook搬运工:Access Tokens

Access Tokens

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.

Generating Access Tokens

User Tokens

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:

  • The Facebook SDK for Javascript generates and persists access tokens automatically. You can learn more about starting the login process in our guide: Getting Started with Facebook Login for Web. You can retrieve the access token by making a call to FB.getAuthResponse which will include an accessToken property within the response.
  • The Facebook SDKs for iOS and Android automatically manage access tokens through their 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.
  • When building an app with on the web without Facebook's Javascript SDK you will need generate an access token during the steps outlined in that document.

Short-Term and Long-Term Tokens

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.

Tokens are Portable

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 Tokens

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 Tokens

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:

Page Admin Roles

Value Description Roles this Applies To

ADMINISTER

Manage admins

Full Admin

EDIT_PROFILE

Edit the Page and add apps

Full Admin, Content Creator

CREATE_CONTENT

Create posts as the Page

Full Admin, Content Creator

MODERATE_CONTENT

Respond to and delete comments, send messages as the Page

Full Admin, Content Creator, Moderator

CREATE_ADS

Create ads and unpublished page posts

Full Admin, Content Creator, Moderator, Ads Creator

BASIC_ADMIN

View Insights

Full Admin, Content Creator, Moderator, Ads Creator, Insights Manager

Using Tokens with different App Types

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 useappsecret_proof for any calls.

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 useappsecret_proof for any calls you make from the server.

Login on Native or Web Client, API Calls from Native or Web Client

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:

  1. Native or web client authenticates and uses the returned short or long-term token to make calls.
  2. Web client authenticates, exchanges the short-term token for a long-term token via a server, token is sent back down to the web client and then the web client and makes calls with the long-term token.
  3. Web client authenticates, exchanges the short-term token for a long-term token via a server, server does code exchange and the client exchanges the code for a long-term token, makes calls with that token. (Used rarely.)

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):

Login on Client, API Calls from Server

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.

Login on Client, API Calls from Client or Server

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.


Changing SDK Access Tokens

There are different ways to explicitly specify which access token to use with an API call in our SDKs:

  • The Javascript SDK FB.api() function can take a parameter access_token.
  • The iOS SDK has an openFromAccessTokenData method
  • The Android SDK can take an access token as a parameter in the Session.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.


Expiration and Extending Tokens

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.

  • Once you've retrieved the long-lived token, you can use it from your server or ship it back down to the client to use there.

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.

Refreshing Long-Lived Tokens

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.

Extending Page Access Tokens

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.

Using Long-Lived Tokens on Web Clients

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.

Generating Long-Lived User Tokens from Server-Side Long-Lived Tokens

Facebook has an advanced option for obtaining long-lived access tokens for apps that:

  1. Have their own authentication system (using a username/password for example)
  2. Store, on their servers, a Facebook access token for people using it that they send to different clients (browser or native mobile apps)
  3. Make API calls from all of those clients

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:

  1. Make a call to Facebook's server from your server using a valid and current long-lived token to generate a code. (This assumes you've already obtained a long-lived token via Facebook Login. If the token you're using is invalid or expired, you'll have to obtain a new one by making the person using your app log in again.)
  2. Securely send that code to the client.
  3. The client then exchanges the code for a long-lived token.
  4. The client can use the long-lived token to post stories or query data.

This is a diagram of the flow:

Getting the code

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

access_token

Yes

Long-lived user access token.

client_secret

Yes

The app's app secret.

redirect_uri

Yes

The redirect URI must be set to the exact value in the app's configuration.

The response will look something like:

{"code": "...."}

Redeeming the code for an access token

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

client_id

Yes

The App ID.

code

Yes

The code returned from Facebook's server.

redirect_uri

Yes

The redirect URI must be set to the exact value in the app's configuration.

machine_id

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 machine_id you should include it here.

The response will look like:

{"access_token":"...", "expires_in":..., "machine_id":"..."}

Returned values are:

Value Description

access_token

A new long-lived access token that you can use for Graph API calls.

expires_in

The number of seconds until this access token expires.

machine_id

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.


Getting Info about Tokens and Debugging

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 about
  • access_token: your app access token or a valid user access token from a developer of the app

The 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.


Handling Errors

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.)

Expired or invalid access tokens

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.

Person has de-authorized your app

{
  "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.

Handling Token Errors in iOS Apps

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.

Handling Token Errors in Android Apps

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


Sizes

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.

你可能感兴趣的:(Facebook搬运工:Access Tokens)