Using User-Level OAuth
This guide walks you through implementing the Authorization Code Flow. This is the standard method for apps that need to act on behalf of a user, such as performing LPR searches or managing hotlists.
Getting access
Step 1: When registering a Flock app with Flock's team, you'll be asked to provide:
- Application Name
- Application Functionality Description
- Redirect URL(s)
Step 2: Receive Credentials
Flock will register the Flock app for you and then provide to you:
client_idclient_secretIssuer URL: The base URL for authentication (e.g., https://login.flocksafety.com)
Obtaining User access tokens with OAuth
How it works: a high-level overview
OAuth allows a user in a Flock customer environment to install your app. At the end of the OAuth flow, your app gains an access token. Your app's access token opens the door to Flock API methods and events. During the OAuth flow, you specify which scopes your app needs. Those scopes determine exactly which doors your app can open.
Implementing an OAuth flow can feel hard because there are a lot of steps, but your app really only has to worry about three steps to make OAuth work: requesting scopes, waiting for a user to give their authorization, and exchanging a temporary authorization code for an access token. Redirecting a user to Flock can be done with a single link.
Why is there a third exchanging step in OAuth at all? Why doesn't Flock send your app an access token directly after the user okays your app? The reason is two-factor authentication. You have to prove both that you have the right temporary authorization code, and that you have your app's client secret.
1. Requesting scopes
While developing your app, you'll determine a minimum list of scopes that your app requires to work. When a user installs your app in their Flock environment, you'll request those scopes.
To request scopes, redirect users to https://login.flocksafety.com/authorize
Include both your app's client ID, and a space-separated list of scopes, such as: scope=openid offline_access_customer-hotlist:write. The full redirect URL will look something like this:
https://login.flocksafety.com/authorize?scope=openid offline_access_customer-hotlist:write&client_id=YOUR_CLIENT_ID
When requesting scopes, you also need to tell Flock where to send your temporary authorization code afterward. Include a redirect_uri parameter in the URL above. The redirect_uri is where Flock will send the user back to, along with the temporary authorization code, once the user okays your app. We recommend the redirect_uri to use HTTPS.
When there are multiple redirect_uri values configured when you initially register your Flock app, the redirect_url parameter must be sent in both the Authorize and Access steps described below, and the parameter value must be the same for both steps - otherwise, you will encounter a bad_redirect_uri error:
- Authorize: You direct the user to the corresponding
/oauth/v2/authorizepath (this can be done with a link or button, for example). Send theredirect_uriin this step. - Redirect: Flock redirects the user to what was specified as the
redirect_uriin the previous step, and adds a verification code to that URL. - Access: Your server retrieves the authorization code from the previous step and sends it to the token API endpoint to exchange that code for a user access token. If you sent a
redirect_urifield in the first step, you must send that same field with the same value in this step.
If you sent more than one redirect_uri when registering your Flock app, but no redirect_uri parameter is sent, the OAuth flow will use the first redirect_uri from the list your sent. You can use the redirect_uri parameter in your oauth/v2/authorize redirect as mentioned above.
There are other important parameters to provider in this link explained below:
Parameters:
response_type: Alwayscodefor this flowclient_id: Your Flock app Client ID.redirect_uri: Your registered callback URL (e.g.,https://yourapp.com/callback).scope: Space-separated permissions (e.g.,openid offline_access custom-hotlist:write).- Include
offline_accessto receive a refresh token
- Include
audience:com.flocksafety.integrations(orcom.flocksafety.integrations.devfor Sandbox).state: A random string you generate to prevent CSRF attacks.
Example URL with all those parameters:
https://login.flocksafety.com/authorize?
response_type=code&
client_id=YOUR_CLIENT_ID&
redirect_uri=YOUR_REDIRECT_URI&
scope=openid offline_access custom-hotlist:write&
audience=YOUR_API_AUDIENCE&
state=RANDOM_STATE_VALUE
2. Waiting for a user to approve your requested scopes
Good news! Your app doesn't really have to do anything.
Prepare for the return of a user by listening for HTTP requests at whatever redirect_uri you specified when registering your Flock app.
3. Exchanging a temporary authorization code for an access token
If all goes well, a user goes through the Flock app installation and okays your app with all the scopes it requests. Then, Flock redirects the user back to your specified redirect_uri.
Parse the HTTP request that lands at your redirect_uri for a code field. That's your temporary authorization code, which expires after ten minutes.
Example:
https://yourapp.com/callback?code=AUTH_CODE_HERE&state=xyz123random
Security Check: Verify thestateparameter if you sent one along with your initial user redirect. If it doesn't match what you sent, consider the authorization a forgery.
Now, you just need to exchange the authorization code for a user access token.
Make a POST request to the token endpoint (https:/login.flocksafety.com/oauth/token):
curl -X POST https://login.flocksafety.com/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "authorization_code",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"code": "AUTH_CODE_FROM_STEP_2",
"redirect_uri": "https://yourapp.com/callback"
}'Once you complete your access call, Slack sends you an HTTP request response containing an access token. It looks something like this:
{
"access_token": "eyJhbGc...",
"refresh_token": "v1.MRr...",
"id_token": "eyJhbGc...",
"token_type": "Bearer",
"expires_in": 1800
}One more suggestion: show the user a nice message once they are redirected and you successfully gain an access token - or, if there's been an error, report that error to the user. The reason the user is redirected back to your app at the end of OAuth is for transparency purposes: the user deserves to know the end of the story, whether your app was installed successfully or not.
More about tokens
Using tokens
The best way to communicate your access tokens - also known as bearer tokens - to Flock is by presenting them in a request's Authorization HTTP header where the full value, including "Bearer", is case-sensitive. This approach is required when using application/json with a write method.
curl -X POST https://api.flocksafety.com/api/v3/reads/search \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"query": "your_search_params"}'Refreshing Tokens
User Access Tokens expire after 30 minutes. Use the refresh_token (valid for 12 hours) to get a new access token.
Best Practice: Proactively refresh your access token before it expires (e.g., after 25 minutes) to avoid service interruptions.
{
"access_token": "eyJhbGc...",
"refresh_token": "v1.New...",
"token_type": "Bearer"
}OpenID Connect Libraries
To help you integrate with Flock Safety's authentication system, here are recommended OpenID Connect libraries for popular programming languages:
| Language | Recommended Libraries |
|---|---|
| JavaScript | - **openid-client ,passport-openidconnect ,express-openid-connect ** |
| Python | - **authlib ,python-jose ,pyoidc ** |
| Java | - **spring-security-oauth2 ,pac4j ** |
| C#/.NET | - **IdentityModel.OidcClient ,Microsoft.AspNetCore.Authentication.OpenIdConnect ** |
| Go | - **coreos/go-oidc ,zitadel/oidc ** |
| Ruby | - **omniauth-openid-connect ,openid_connect ** |
| PHP | - **jumbojett/OpenID-Connect-PHP ,league/oauth2-client ** |
Token Structure
Flock Safety access tokens include custom claims:
- Note that
https://flocksafety.com/external_idrefers to a user's unique external ID <YOUR_AUDIENCE>will differ based on your application
{
"https://flocksafety.com/external_id": "24e07116-4ce4-4e76-b19c-61a80c430960",
"https://flocksafety.com/organization_id": "cd8d9c47-cf0d-4c24-9fdd-4bbdf9f54086",
"https://flocksafety.com/timezone": "US/Eastern",
"https://flocksafety.com/vendor_id": "2c0ff6d6-c2ca-40ae-8828-127fc38e5c3b",
"https://flocksafety.com/is_user": true,
"iss": "https://login.flocksafety.com",
"scope": "openid lpr-alerts:subscribe lpr-alerts:subscribe.image-urls lpr-devices:read",
"aud": "<YOUR_AUDIENCE>",
"iat": 1763758772,
"exp": 1763760572,
"azp": "<SOME_CLIENT_ID>"
}Errors
Below are some errors you may encounter and reasons for encountering them:
bad_redirect_uri: Occurs when there are multipleredirect_uriparameter values configured and they do not match.invalid_scope: Occurs if requesting a non-existent scope or requesting a set of scopes that are in conflict with each other.
Support & Resources
- OpenID Connect Specification: OpenID Connect Core
Updated 20 days ago