Authorization
Fitbit requires applications use the OAuth 2.0 Authorization Framework to securely authorize access to Fitbit user data. Fitbit recommends using the best OAuth 2.0 or HTTP client library available for your preferred application platform and programming language. Many times, these libraries contain sample code to help you get started. Fitbit’s Web API uses a common implementation of the OAuth 2.0 specification, so a Fitbit-specific library is not required. For a list of OAuth 2.0 libraries suggested by our developer community, see Libraries and Sample Code
For a complete interactive walkthrough of the authorization flow see the OAuth 2.0 Tutorial.
There are three main steps to OAuth 2.0:
- Request authorization from a user to access their data.
- Query the user's data using the provided access token.
- Refresh expired access tokens with the corresponding refresh token.
Authorization Code Grant Flow with PKCE
There are several authorization flows specific to the OAuth 2.0 protocol. For best security, Fitbit recommends using the Authorization Code Grant Flow with Proof Key for Code Exchange (PKCE) defined by RFC 7636. PKCE supplements the Authorization Code Grant flow with a dynamically created cryptographically random key (“code verifier”) and its transform value (“code challenge”) to verify the client. Any application will get added security with the ability to mitigate authorization code interception attacks. This section will demonstrate in five steps how an application obtains the user’s authorization using PKCE.
Step 1 - Generate the Code Verifier and Code Challenge
The application needs to generate two values to keep the OAuth 2.0 protocol and the Fitbit user data secure:
- A cryptographically random value between 43-128 characters long called a code verifier
- A SHA-256 hash of the code verifier, base64url encoded with padding omitted, called the code challenge
Transforming the code verifier into the code challenge requires the use of libraries that implement the SHA-256
hash and Base64Url encoding specifications. The optional
Base64Url padding characters
(=
) should be omitted. For example, if the code verifier is
01234567890123456789012345678901234567890123456789
,
the pseudocode base64UrlEncode(sha256Hash(code_verifier))
should produce a code challenge of
-4cf-Mzo_qg9-uq0F4QwWhRh4AjcAqNx7SbYVsdmyQM
.
Step 2 - Request Authorization to Fitbit User Data
Using a web browser, the application calls the Authorize endpoint to display Fitbit's Authorization page to the user. If necessary, the user may need to log in with their Fitbit credentials.
Mobile Development: Use either custom tabs (Android) or the SFSafariViewController (iOS) instead of their webview counterparts. This allows the Fitbit user to know they are logging into the secure Fitbit site.
The required query parameters are:
client_id
: The Fitbit API application ID from https://dev.fitbit.com/apps .scope
: A space-delimited list of data collections requested by the application.code_challenge
: The base64url-encoded SHA256 hash of the code verifier.code_challenge_method
: S256response_type
: code
For example, the following URL will load the Authorization page
https://www.fitbit.com/oauth2/authorize?client_id=ABC123&response_type=code &code_challenge=<code_challenge>&code_challenge_method=S256 &scope=activity%20heartrate%20location%20nutrition%20oxygen_saturation%20profile %20respiratory_rate%20settings%20sleep%20social%20temperature%20weight
The user will select the data collections, or scopes, they want to share with the application. If the user has previously consented to the same requested scopes, the flow will skip this UI and proceed directly to the next step.
NOTE: The application is not allowed to enable all scopes by default or force a user to enable all scopes. Instead, we suggest encouraging the users to enable all scopes by stating something like “For the best user experience, we recommend you enable all listed scopes” See Fitbit’s Platform Terms of Service for more details. It is ultimately up to the Fitbit user whether or not all of the scopes are enabled. Therefore, the application should not break if a scope is not granted.
Step 3 - Retrieving the Authorization Code
Once the user authorizes access to their data, Fitbit returns the user back to the application using the redirect URL. Appended to the redirect URL is the authorization code located between the "code" parameter name and the string "#_=_". Following is an example of the redirect URL with the authorization code highlighted:
https://myapp.com/callback?code=d62d6f5bdc13df79d9a5f#_=_
Mobile Development: Fitbit recommends using a Universal Link (iOS) or App Link (Android) when redirecting back into the application.
Step 4 - Exchange the Authorization Code for the Access and Refresh Tokens
The application should extract the authorization code from the redirect URL and exchange it for the access token and refresh token. The tokens are obtained by calling the /oauth2/token endpoint and providing the following parameters within the body of the HTTPS POST request. See Token API for more information
The required query parameters are:
client_id
: The Fitbit API application ID from https://dev.fitbit.com/apps.code
: The authorization codecode_verifier
: The code verifier value from step 1.grant_type
: authorization_code
The application type (server, client or personal) defined in the registered application settings determines how the Token API endpoint is authorized to Fitbit.
Server Application Type
Server application types must authenticate themselves using the client secret available in application settings. This provides the highest level of security to the OAuth 2.0 flow. However it should only be used by applications that can securely store the client secret, such as apps running on a web server. Notably, the client secret should never be included in application source code or stored on an end-user device where it can be discovered.
These applications authenticate by specifying the Authorization header to the request, and include the "Basic" token. The basic token is a base64-encoded concatenation of the client ID and secret, separated by a colon:
BASE64ENCODE(<client_id>:<client_secret>)
For example, with a client ID “ABC123” and secret “DEF456”,
POST https://api.fitbit.com/oauth2/token Authorization: Basic QUJDMTIzOkRFRjQ1Ng== Content-Type: application/x-www-form-urlencoded client_id=ABC123&code=<authorization_code>&code_verifier=<code_verifier>&grant_type=authorization_code
Client and Personal Application Types
Client and personal application types can call /oauth2/token without any additional security requirements. This should only be used when the application cannot safely store the client secret. For example,
POST https://api.fitbit.com/oauth2/token Content-Type: application/x-www-form-urlencoded client_id=ABC123&code=<authorization_code>&code_verifier=<code_verifier>&grant_type=authorization_code
Step 5 - Receive the Access and Refresh Tokens
The Token endpoint returns a JSON-encoded response that includes:
- The user id of the person who authorized access
- The access token used to query the user's data
- The refresh token the application will use to obtain a new access and refresh token pair
- The lifespan of the access token in seconds
- The scopes the user enabled on the Fitbit Authorization page
We recommend the application store this information and refer back to it as needed. If the application loses the refresh token for a user, the user will need to re-authorize the application, again.
Example
{ "access_token": "<access_token>", "expires_in": 28800, "refresh_token": "<refresh_token>", "scope": "activity heartrate nutrition oxygen_saturation respiratory_rate settings sleep temperature weight", "token_type": "Bearer", "user_id": "<user_id>" }
Other Supported Authorization Flows
Authorization Code Grant Flow (without PKCE)
This is the original variant of Authorization Code Grant flow, defined by RFC 6749, which is superseded by PKCE. Unlike PKCE, this variant does not support the code verifier or challenge values when requesting user authorization. Instead, two other methods are used to help secure this flow.
- Only server application types may omit PKCE. This means that a client secret must be used when obtaining access and refresh tokens
- To protect against Cross Site Request Forgery (CSRF) attacks, the application should pass an anti-forgery token in the "state" parameter when showing the Authorization page. This should be an unguessable value associated with the user. Fitbit will pass back this value as a query parameter in the redirect URL, and your application must verify that it matches.
Implicit Grant Flow
Defined by RFC 6749, this authorization flow is no longer recommended as an OAuth 2.0 best practice. Unlike the Authorization Code Grant flow, the authorization page directly returns an access token making the consent process highly susceptible to a number of security attacks. When using the Implicit Grant flow,
- The registered application must be configured with the "client" OAuth 2.0 Application type.
- The user may specify a lifetime for the access token up to one year.
- After the user consents, the redirect URL contains the access token. A refresh token is not provided.
- Once the access token expires, the user will need to authorize the application again.
With the Implicit Grant FLow, Fitbit will pass the following parameters
to the application's redirect URL after the #
access_token | The access token your application should use to call endpoints on behalf of the user. |
expires_in | The lifetime of the access token in seconds. |
scope | A space-separated list of scopes the user authorized. |
state recommeded |
Provides any state that might be useful to your application when the user is redirected back to your application. This parameter will be added to the redirect URI exactly as your application specifies. Fitbit strongly recommend including an anti-forgery token in this parameter and confirming its value in the redirect to mitigate against cross-site request forgery (CSRF). |
token_type | Supported: Bearer |
user_id | The Fitbit user id |
Client Credentials
Defined by RFC 6749, this authorization flow is used with specific Fitbit API endpoints related to business operations. It is not supported by the public Web APIs to retrieve Fitbit user data. See Client Credentials