Integrate Frontegg via OAuth
Authenticate users effortlessly with hosted login. Frontegg's pre-configured Login Box enables your customers to sign up and log in seamlessly to your application. Built on the OpenID Connect protocol, Frontegg’s hosted login ensures secure and reliable user authentication.
Integrate hosted login into your application with just a few simple code modifications.
Step 1: Configure hosted login
In the Frontegg portal, navigate to the relevant [ENVIRONMENT] → Authentication → Login Method and ensure that Hosted Login is selected and insert the redirect URLs that you are redirecting users to after they login. If the requested redirect URL won't be in that list, the initial request to /authorize
will get an error.
Step 2: Generating verifier and challenge code
Frontegg supports the PKCE flow, recommended for OAuth implementations on the client side. This flow secures the token exchange using a code_verifier that must match the code_challenge generated during the initial /authorize
request. If implementing OAuth through your backend, code_verifier
and code_challenge
are not required. In such cases, refer to the Authorization Code examples.
Below is a snippet on how to generate the verifier and challenge code:
export function createRandomString(length: number = 16): string { let text = ''; const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; for (let i = 0; i < length; i++) { text += possible.charAt(Math.floor(Math.random() * possible.length)); } return text; } export async function generateCodeChallenge(codeVerifier: string): Promise<string> { const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(codeVerifier)); // @ts-ignore return btoa(String.fromCharCode(...new Uint8Array(digest))) .replace(/=/g, '') .replace(/\+/g, '-') .replace(/\//g, '_'); } const code_verifier = createRandomString(); const code_challenge = await generateCodeChallenge(code_verifier);
Step 3: Request authentication code
On your application's signup and login pages, add a button for the end user to click when logging in using hosted login. When your customers click that button, send a request to /authorize
endpoint as in the example below:
curl --location --request GET 'https://[your-frontegg-subdomain].frontegg.com/oauth/authorize?response_type=code&redirect_uri=[redirect_uri]&client_id=[client_id]&scope=openid+email+profile&code_challenge=[code_challenge]
Parameter | Description | Required |
---|---|---|
client_id | Your client id from the Administration page of the Frontegg portal | required |
redirect_uri | One of the redirect URLs you configured in your Frontegg portal | required |
state | A value that you provide here, and that will be returned to you in the token exchange. state can be any string value you want. Use a randomly generated unique value to prevent cross-site request forgery attacks. state also can be used to encode information about the user sending the authentication request, like what page they are visiting in the application. | optional |
code_challenge | A value that you provide so that you can use it in the token exchange with PKCE for additional security. | optional |
app_id | An app identifier for accounts with multiple applications. Can be copied from [ENVIRONMENT] → Applications → [App_Name] → ID | optional |
login_hint | An attribute that can be used for pre-filling user's email programmatically | optional |
A successful response redirects to the redirect_uri
with an authorization code
and, if provided, a state
.
{redirect_uri}? code={authorization_code} &state={state}
You now have the authorization code that you requested. Use the authorization code to request an access token, as explained below.
If you included a state parameter in the request, you should receive the same value here in the response. It is a good idea to compare the state
here to the state
you sent in the request to make sure that the values are identical.
Step 4: Exchange tokens
The next step is to send a request to exchange tokens. With the authorization code in your possession, exchange the code for an access token for the user. When a PKCE flow is used, it is required to pass code_verifier
. If standard authorization code flow is implemented you should pass environment / application / API token credentials (clientId
and secret
) as a base64 encoded Authorization
header.
curl --location --request POST 'https://[your-frontegg-subdomain].frontegg.com/oauth/token' \ --data-raw '{ "redirect_uri": "redirect_uri", "grant_type": "authorization_code", "code": "authorization_code", "code_verifier": "code_verifier" }'
For grant_type
, the value authorization_code
is what you should put. It is a value, not a parameter for you to fill in. For the remaining keys, for the values to insert into the body of your POST request, please see the following table:
Parameter | Description | Required vs Optional |
---|---|---|
authorization_code | The authorization code is the authorization_code you receive after being redirected at the end of Step 2 above | required |
redirect_uri | This must be the same redirect URL that you provided for the authorization request | required |
code_verifier | This must be the code_verifier that was generated along with the code_challende request | required if code_challenge was sent in the authorization request |
If the code to token exchange is successful, the endpoint will return id_token
and access_token
:
{ "token_type": "Bearer", "access_token": "access_token", "id_token": "id_token", "refresh_token": "refresh_token", "expires_in": xxx }
Step 5: Refresh tokens
The access token that was returned in the previous step can be refreshed using the provided refresh_token
. If standard authorization code flow is implemented, you should pass environment / application / API token credentials (clientId
and secret
) as a base64 encoded Authorization
header.
See an example for a refresh request below:
curl --location --request POST 'https://[your-frontegg-subdomain].frontegg.com/frontegg/oauth/token' \ --header 'Content-Type: application/json' \ --data-raw '{ "grant_type":"refresh_token", "refresh_token":"refresh_token" }'