OAuth 2.0 for Native Apps
April 13, 2022
In order to obtain an access token for integrating a desktop or mobile app with the FamilySearch API, a user will need to complete an authentication and authorization process using OAuth 2.0. This will be done by using the OAuth 2.0 Authorization Code Flow. This guide will help you to learn how this works, what is required, and provide some ideas on how you might approach this integration. The following specifications can be referenced to obtain further understanding and implementation details.
Auth Process Overview
This section describes the experience your users will complete in order to complete the authorization flow. You have likely experienced this flow when authenticating an app with a service like Google or Facebook. Here are the basic steps the user will experience.
Step 1: User clicks to login
In this step, the native app will prompt the user to login with FamilySearch. The user will click on a button or link that says something like "Login with FamilySearch". This action will take the user away from your application and to a web browser.
Step 2: User logs in
In this step, the user will be viewing the FamilySearch authentication page in a web browser. The user will use his or her FamilySearch credentials to login. In the future, it is likely that additional identity providers will be made available to the user.
If the authorization request is configured to use OpenID Connect, it is possible that the user could already be logged in on FamilySearch and the user will automatically advance to the next step.
Step 3: User consents
In this step, the user will be prompted with a request to grant permission for the native app to access FamilySearch data on behalf of the user. The user will click "Accept" or "Cancel" and will be taken back to the native app's redirect URI.
Step 4: User redirects to app
Depending upon the approach taken for the redirection, the user will either return directly to the app experience or will be viewing a success page that prompts the user to close the page and return to the app.
If the user accepted the permission, the app should receive a code to be exchanged for tokens. If the user canceled, the app should receive an error code and message indicating that the user declined consent.
Step 5: User accesses FamilySearch data
In this step the application will exchange the authorization code for tokens. Upon successful exchange, the app will receive an access token and a Refresh Token. The access token will be used with requests to the FamilySearch API. The Refresh Token will be used to exchange for a new set of tokens once the access token expires. This will enable the app to continue to access the FamilySearch API on behalf of the user for an extended period of time without needing to constantly prompt the user to login.
Desktop User Experience
Web User Experience
Approach for Redirects
Native apps may take different approaches for redirecting the user back to the application. This section describes different strategies for handling the redirect along with the potential advantages and challenges for each approach. In all cases, the app developer will need to register the desired Redirect URIs with the FamilySearch system. This will be discussed in the next section.
Register Custom Protocol Handler
Some modern operating systems support a mechanism for registering a custom protocol handler which can be used to open up a specific native application while passing parameters to the app. This approach is supported very well on iOS and Android operating systems and is the recommended approach for handling OAuth 2.0 redirects for mobile applications.
When using a custom protocol handler, the redirect URI will look something like this.
com.your-domain.your-app://familysearch-auth
Please note that some platforms recommend using a reverse domain name convention to ensure uniqueness com.your-domain.your-app.
In order to use this type of redirection, the operating system must know that your-unique-app-name is associated with your application. The process for registering the custom protocol varies across operating systems and development environments.
Potential Advantages
One major advantage to using this approach is that the user is seamlessly redirected back to the native app and results in a better user experience. As mentioned earlier, mobile operating systems handle this flow very well and the user is able to reenter the application with the URI containing the needed parameters to complete the auth process.
Potential Challenges
While possible, this approach can be more difficult for desktop apps. Typically, the operating system will launch a new process of the desktop app, passing the query parameters as an argument. The desktop app would need to detect these parameters and use some kind of interprocess communication mechanism to communicate the variables back to the original process from which the user started the flow.
Supporting this method for cross-platform desktop applications can be difficult as Windows, Mac, and Linux all handle registering protocol handlers in different ways.
Listen on Loopback Port
Another approach for handling the redirect involves opening up a network handler on the loopback address and listening on a specific port. The native app acts as a very simple web server running on the local machine. When the user is directed to the redirect URI, the browser makes the request to the native app's web server, passing the needed parameters in the query string. The native app is then able to complete the token exchange process and responds to the browser with a page prompting the user to close the page and to return to the app.
When using the loopback approach, your redirect URI will look something like this.
IP v4
http://127.0.0.1:57938/familysearch-auth
IP v6
http://\[::1\]:57938/familysearch-auth
Potential Loopback Advantages
This is the simplest way to capture the redirect with a desktop application. There is no need for complex interprocess messaging.
Potential Loopback Challenges
Users can potentially get lost getting back to your application. It is important to give clear instruction on your response page that guides the user back to your application.
Some desktop firewall software has been known to block the listening on the local port. This is most problematic when using localhost instead of IP address or when the port used falls within a reserved range. Make sure that your app uses a loopback IP address and that the port number is greater than 1024 to avoid Windows UAC privileged user requirements.
Listen with a Server
If you have the capability to run a secure web service, you can use it to handle the redirect. This process would entail the following basic steps.
Native app establishes a session with secure web service.
- User is sent to the Authorization URL in browser.
- User completes Authorization flow.
- User is redirected to secure web service.
- User closes browser window and returns to app.
- Native app retrieves token from server based upon established session.
- When using the secure server approach, your redirect URI will look something like this.
https://example.com/familysearch-auth
Potential Server Advantages
This is a reliable and secure option for handling the redirect.
Potential Server Challenges
This approach introduces additional infrastructure and technology to manage.
Redirect URIs
Depending upon the approach chosen for your redirect, you will need to register your redirect URI with FamilySearch. Please know that your app key (client\_id
) can be associated with multiple redirect URIs.
If you wish to register redirect URIs for the Beta or Production environments, please contact [email protected].
In your email to register your redirect URIs, please make sure to include the following information:
App Key (client_id):
Environment(s): [Integration,Beta,Production]
Redirect URI(s):
PKCE
The Proof Key for Code Exchange (PKCE) is a protocol that helps to ensure that the process that initiated the flow is the same process to complete the flow after the redirect. The OAuth 2.0 Simplified book provides a fantastic chapter which describes PKCE and how to implement it.
Authorization Request
The Authorization Request is the request made by the user's browser to the location which will prompt the user authentication and consent. To implement, your app will construct the Authorization Request URL with the appropriate query string parameters. The following is information to help you construct the request.
FamilySearch Authorization Resource Documentation
The following are the query string parameters to be used.
Parameter | Value |
---|---|
client_id | This is the app key assigned to your application. |
redirect_uri | This is the URI used to complete the flow. If the URI hasn't been registered with FamilySearch, you will receive an error. |
response_type | This must be set to code. |
state | (recommended) This parameter will be returned to your redirect URI. For more information, see the section "RedirectURLs and State" in the OAuth 2.0 Simplified book. |
code_challenge | This is the hashed and encoded random string described in the PKCE section. |
code_challenge_method | This should be set to S256 if using a SHA 256 hash method. Set to plain if your application is unable to hash the code verifier. |
scope | This can be set to openid if your app desires to use OpenID Connect. See the OpenID Connect documentation for more details. |
Note that All values of the query string parameters should be percent encoded.
Example Authorization Request URL
https://ident.familysearch.org/cis-web/oauth2/v3/authorization?client_id=a02f100000SSxKMAA1&redirect_uri=http%3A%2F%2F127.0.0.1%3A57938%2Ffamilysearch-auth&response_type=code&state=237589753&code_challenge=1j_SZ7VLys6EddDGmv6K69OMNgV2KfGG5T4Oaz1cDIE&code_challenge_method=S256&scope=openid
Redirect After Success
http://127.0.0.1:57938/familysearch-auth?code=2952-60121-6-53-114117-3157-8667122-10822-13111-14-21-32-110-11471-95-11863-6-5130-4241-56&state=237589753
Handling the Redirect
After the user completes the authentication and grants permission, the browser will redirect back to the redirect_uri, appending the following query string parameters.
Parameter | Value |
---|---|
code | If successful, this parameter will contain the authorization code that will be used to exchange for tokens, which will be discussed in the next section. |
state | If provided on the authorization request, this parameter will contain the same value. |
error | If unsuccessful, this will contain an error code. For information on possible error codes, see Section 4.1.2.1 of the OAuth 2.0 Specification. |
error_description | If unsuccessful, this will contain a human readable (English) description of the problem. |
Success Example
http://127.0.0.1:57938/familysearch-auth?code=2952-60121-6-53-114117-3157-8667122-10822-13111-14-21-32-110-11471-95-11863-6-5130-4241-56&state=237589753
Error Example
http://127.0.0.1:57938/familysearch-auth?error=access_denied&error_description=User+declined+consent.
Token Request
The Token Request is used to exchange the authorization code for tokens. This is done by performing a HTTP POST to the Token Resource. The following is information to help you construct the request.
The body of the POST should contain the following parameters, encoded as application/x-www-form-urlencoded form encoded parameters. Please refer to the resource documentation for setting appropriate headers.
Parameter | Value |
---|---|
client_id | This is the app key assigned to your application. |
code | This is the authorization code received from the redirect. |
grant_type | This must be set to authorization_code. |
redirect_uri | This should be the redirect URI used when initiating the flow. |
code_verifier | This is the original random string used to generate your code challenge. |
The response will contain a JSON document containing the access_token, refresh_token, and if configured for OpenID Connect, an id_token.
Example Request
POST /cis-web/oauth2/v3/token HTTP/1.1
Host: ident.familysearch.org
Content-Type: application/x-www-form-urlencoded
client\_id=a02f100000SSxKMAA1&grant\_type=authorization\_code&redirect\_uri=http://127.0.0.1:57938/familysearch-auth&code\_verifier=p5bnlTNHiqUm6jnTvNKD6RXGCq738wXEVFSybUjgW0k&code=-29-107-1068390-12231-984831639486-86-105-89-7251334-1512192-96124-35611270-87-4045
Example Response
<table><tbody><tr><td colspan="1" rowspan="1"><p>HTTP/1.1 200 OK<br>Date: Tue, 03 Nov 2020 22:29:44 GMT</p><p>Content-Type: application/json;charset=UTF-8</p><p>Content-Length: 694</p><p>Connection: keep-alive</p><p>Cache-Control: no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0</p><p>Content-Encoding: gzip</p><p>Content-Language: en-US</p><p>Expires: Tue, 03 Jul 2001 06:00:00 GMT</p><p>Last-Modified: Tue Nov 03 22:29:44 UTC 2020</p><p>Pragma: no-cache</p><p>Server: nginx/1.18.0</p><p>X-Robots-Tag: noindex, nofollow, noarchive, nosnippet, notranslate, noimageindex</p><p></p><p>{</p><p>"access_token": "b69cc237-c1c7-4aaf-8ffb-cb443486666b-integ",</p><p>"id_token":"eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvaW50ZWdyYXRpb24uZmFtaWx5c2VhcmNoLm9yZ1wvc2VydmljZVwvaWRlbnRcL2Npc1wvY2lzLXdlYlwvb2F1dGgyXC92MyIsInN1YiI6ImNpcy51c2VyLk1NTU0tRERIMiIsImF1ZCI6ImEwMmYxMDAwMDBTU3hLTUFBMSIsInNlc3Npb25JZCI6ImI2OWNjMjM3LWMxYzctNGFhZi04ZmZiLWNiNDQzNDg2NjY2Yi1pbnRlZyIsImV4cCI6MTYwNDUyNjc5MSwiaWF0IjoxNjA0NTE5NTkxfQ.kO4bDxYRWdBeLW0_x2bc2AQjGCwZ1iL7rlKFawA7rxIRZj3B_nUI0TnBmak92NjzPaa72wz0PWsfKV1llATpUMypXevpR08Pk6BkFuZrA7HP5w5pyHGwo8e1kORPtlr93uKU9FnFUVhAuTjGP0PQwDu3kBwAm72EmeTnVP_NxEfBi_HT8Pq2oMRN1ovUikD8FCnJi67Gn-ppN5EgSdq2TDU6svQpz8J-oyAJCFHRGd62wlF63VURfktMMsVYKa_wmS0PAjhH4QB_uPnsSgjEYp7q3XVNxPHQRy5dWFXhNKlJt3mvpCHzwSfvGvhSIXIlmJW7ganuNuvLZ5VwjY05yw",</p><p>"refresh_token": "-84169492-45-40-107571079511378-2089-7-1108766-34-4620883010-8022-8110215-4-1-103",</p><p>"token_type": "Bearer"</p><p>}</p></td></tr></tbody></table>
Refresh Tokens
Refresh tokens are used to exchange for new tokens once the current, shorter-lived tokens expire. This enables your app to interact with the FamilySearch API for an extended period of time without needing to prompt the user to login as frequently.
The Refresh Token will be valid for 90 days. The Access Token expires after a period of inactivity with a max life of 24 hours.
Your application can detect the expiration of the access token when a 401 response code is returned. Once your application detects that the Access Token is expired, you can exchange the Refresh Token for a new set of tokens.
Your app key must be configured to enable Refresh Tokens. To enable Refresh Tokens for your key, please send an email to [email protected]. This can be done at the same time you request you redirect URI(s). Please make sure to include your app key in the email.
Token Request with Refresh Token
The Token Request can be made with a Refresh Token to acquire new tokens. This is discussed in Section 6 of the RFC 6749 OAuth 2.0 Spec.
The format of the Token Request will be very similar to the request referenced in the above Token Request section, but the parameters will be as such.
Parameter | Value |
---|---|
grant_type | This must be set to refresh_token. |
refresh_token | This should be set to the value of your current Refresh Token. |
A successful request will receive a response with a new set of tokens. Your app should discard the used Refresh Token and keep the new token for the next refresh.
Example Request
POST /cis-web/oauth2/v3/token HTTP/1.1
Host: ident.familysearch.org
Content-Type: application/x-www-form-urlencoded
grant\_type=refresh\_token&refresh\_token=-84169492-45-40-107571079511378-2089-7-1108766-34-4620883010-8022-8110215-4-1-103
Example Response
HTTP/1.1 200 OK
Date: Tue, 03 Nov 2020 22:29:44 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 694
Connection: keep-alive
Cache-Control: no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0
Content-Encoding: gzip
Content-Language: en-US
Expires: Tue, 03 Jul 2001 06:00:00 GMT
Last-Modified: Tue Nov 03 22:29:44 UTC 2020
Pragma: no-cache
Server: nginx/1.18.0
X-Robots-Tag: noindex, nofollow, noarchive, nosnippet, notranslate, noimageindex
{
"access\_token": "8060ac21-72c8-444b-9845-d9cfd31af525-integ",
"id\_token":"eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvaW50ZWdyYXRpb24uZmFtaWx5c2VhcmNoLm9yZ1wvc2VydmljZVwvaWRlbnRcL2Npc1wvY2lzLXdlYlwvb2F1dGgyXC92MyIsInN1YiI6ImNpcy51c2VyLk1NTU0tRERIMiIsImF1ZCI6ImEwMmYxMDAwMDBTU3hLTUFBMSIsInNlc3Npb25JZCI6IjgwNjBhYzIxLTcyYzgtNDQ0Yi05ODQ1LWQ5Y2ZkMzFhZjUyNS1pbnRlZyIsImV4cCI6MTYwNDUyNzI0MCwiaWF0IjoxNjA0NTIwMDQwfQ.WvGpCcY1kfi2hvHseJqePmZGrbEMU8tmsSs9IpcvPacuwcevGhIczSGCB\_51JdBXMFIicKgowt8lj\_k5CYt7ATQjxz1ICiTkvBJsM\_xaPcAAkPcN65OKdxxhaStBGypkyrMPDAfP\_X3UbXHLJ\_EDbG5ffW0JnnM8c-5RIhbhjRLypFEc1kPjLKtlVbOuHt9kPcIkDzzdtiZEQQRnI7nabN9NQbN8bmrv6xexIJgeBAc9iybWMM3x\_NsXd9zfKsxPNosjTj0QovAh2JrJSCpHXwimst2YWCe6Rs7PXloI9UDpNcDlPbiwhPdhqpMOIp8zUoGMNeBz0-MUfrElpseqcg",
"refresh\_token": "11725-3632127-8773105-8620-58120-97-5086-116117-61-8510384-9058735-50-1217-17826",
"token\_type": "Bearer"
}
Requirements and Best Practices
Please observe the following requirements and best practices.
Requirements
- Native applications must use PKCE as part of the authorization process.
- The Authorization flow must be performed by the system's default web browser.
- In the case of iOS, it is acceptable to use SFSafariViewController.
- In the case of Android, it is acceptable to use Chrome Custom Tabs in Chrome 45+.
Best Practices
When using the loopback address for redirect, it is advised to:
- Use http://127.0.0.1:{port} (IP v4) or http://[::1]:{port} (IP v6) instead of localhost. Using localhost has been known to cause problems with some client firewalls.
- Use a port number greater than 1024 to avoid conflict with reserved ports and to avoid Windows UAC privileged user requirements.
Helpful Implementation Resources
- AppAuth.io - Code libraries for iOS, MacOS, Android, and native JavaScript
- OAuth 2.0 Simplified Book:
- Chapter 6 "Mobile and Native Apps"
- Chapter 15 "OAuth for Native Apps"
- Chapter 17 "Protecting Mobile Apps with PKCE". This also applies to desktop apps.
- Guidance for OAuth 2.0 for Native Apps by Google
- Sample OAuth 2.0 Apps for Windows by Google
- Sample Code in Multiple Languages for PKCE Code Verifier and Challenge by Auth0
- Guide for iOS and Android Custom Protocol Handlers by Okta
Updated 2 months ago