FlutterFlow

FlutterFlow provides a simple, low-code platform for building Flutter applications. This guide walks you through integrating Descope authentication into your FlutterFlow project.

We'll use OIDC Endpoints along with the default OIDC federated application available in the Descope Console to complete the integration.

With the following setup, you will be able to build secure login flows using Descope's visual editor, support advanced features like SSO, passwordless login, and MFA, and manage users and sessions through Descope's platform all within your FlutterFlow application.

Step 1: Configure Authentication in FlutterFlow

Start by identifying the key pages in your app where authentication will occur. At a minimum, you'll need:

  • A login page to initiate the authentication process
  • A redirect/loading page to handle the redirect after login
  • A post-login page (e.g., home or dashboard) to navigate to once authentication is complete

Custom authentication should then be enabled for the FlutterFlow project. In your FlutterFlow project settings:

  1. Go to the Authentication section
  2. Enable authentication
  3. Set the Authentication Type to Custom
  4. Assign the Entry Page to your login page
  5. Assign the Logged In Page to your post-login destination

Flutterflow authentication settings

Step 2: Use Descope's OIDC Endpoints

To authenticate using our OIDC endpoints, you must use the endpoints included under the default OIDC app in the Console. First, use /authorize to complete the flow and receive an authorization code. Then, the /token endpoint to receive the access, refresh, and id tokens for the user.

These endpoints can be found as part of the default OIDC application that exists under the Federated Apps section of the Descope Console. They are listed under SP Configuration.

These URLs will use your custom domain if it is configured for your Descope project. Read the Custom Domain docs to learn more.

OIDC endpoints available in Descope

This is the action flow for the login page on FlutterFlow:

Flutterflow actions for login page

The first step in starting the login process is generating PKCE values for the OIDC token exchange.

Step 3: Generate PKCE Values

To securely use OIDC, you'll implement PKCE (Proof Key for Code Exchange).

To generate the PKCE values in FlutterFlow, create a custom action in the Custom Code section of the FlutterFlow app. This custom action should add the pkce dependency by adding this line pkce: ^1.1.0 to the right hand side of the screen.

The action should then contain the following code:

// Automatic FlutterFlow imports
import '/backend/schema/structs/index.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/actions/index.dart'; // Imports other custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom action code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
 
import 'dart:math';
 
import 'package:pkce/pkce.dart';
 
Future<dynamic> pkce() async {
  const charset =
      'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  final random = Random.secure();
  final length = 32;
 
  final pkcePair = PkcePair.generate();
  final state =
      List.generate(length, (_) => charset[random.nextInt(charset.length)])
          .join();
 
  debugPrint(pkcePair.codeChallenge);
 
  return {
    "codeVerifier": pkcePair.codeVerifier,
    "codeChallenge": pkcePair.codeChallenge,
    "state": state
  };
}

This will generate the code challenge, verifier, and state needed for the OIDC Token Exchange. It should then be formatted into an App State variable as a custom data type under the App Values section of the FlutterFlow app. This variable should be persisted so that the code verifier is still available after returning from the flow.

Step 4: Launch the Authorization Request

A authorization code is returned as a parameter in the URL after redirecting from a flow from the /authorize endpoint.

The sign in button on your login page should use the Launch URL action with the following URL:

 https://api.descope.com/oauth2/v1/authorize
    ?response_type=code
    &client_id={DESCOPE_PROJECT_ID}
    &redirect_uri={YOUR_REDIRECT_URI}
    &scope=openid
    &code_challenge={PKCE_CODE_CHALLENGE}
    &code_challenge_method=S256
    &state={STATE}

This URL should use your custom domain if it is configured for your Descope project. Read the Custom Domain docs to learn more.

The following parameters need to be completed:

  • Client ID: This is your Descope Project ID which can be found in the Console.
  • Redirect URI: This is where you want the flow to redirect to, this guide will create a /loading page on the FlutterFlow app to redirect to.
  • PKCE Code Challenge: Must be generated on every authentication, read above section.
  • State: Used to prevent CSRF, generated on every authentication, read above section.

After this URL launches and the flow runs, it will redirect back to the URI specified in the authorization request. In this guide, it will redirect to a loading page that will continue the authentication process as soon as the page loads.

Step 5: Exchange the Code for Tokens

Flutterflow actions for loading page

After redirecting back to the app from the flow, you should be on the loading page. This loading page should have the action flow trigger On Page Load to make the API call to the /token endpoint. This API call should be created in the API call section of FlutterFlow as a POST request to https://api.descope.com/oauth2/v1/token.

The API call should have the following headers and body:

Headers:

  • Content-Type: application/x-www-form-urlencoded.
  • Authorization: Basic, this should be a base64 encoded version of the string YOUR_DESCOPE_PROJECT_ID:.

Body:

  • grant_type: authorization_code.
  • code: This comes from the parameter in the URL upon redirect from the flow.
  • redirect_uri: Should be exactly the same as the redirect URI used for /authorize.
  • client_id: This is the Descope Project ID.
  • codeVerifier: This is generated at the same time as the PKCE Code Challenge, more details on PKCE generation below.

Step 6: Store and Use Token Response

This request will return a response containing an access token, refresh token, id token, and a token expiry time. This is all necessary for logging in using FlutterFlow's custom authentication. The response from the /token endpoint is stored as a Page State variable in a custom data type created on the Data Schema page in FlutterFlow.

The Response data type should include the following:

  • access_token: String
  • refresh_token: String
  • expires_in: Integer
  • id_token: String
  • token_type: String
  • scope: String

The tokens from the response are then passed into FlutterFlow's custom authentication log in action. When the expires_in value is passed into the action, it needs to be converted into the DateTime in seconds from Epoch that the tokens will expire rather than time until expiration. This can be done with a custom function and the code below:

DateTime incrementExpiryTime(int seconds) {
  DateTime now = DateTime.now();
  return now.add(Duration(seconds: seconds));
}

Step 7: Configuring Token Refresh

The access token generated on login expires after 10 minutes by default so to maintain the session past 10 minutes, the refresh token must be used to generate a new access token.

In FlutterFlow, create a new API call to the /token endpoint with the following headers and body:

Headers:

  • Content-Type: application/x-www-form-urlencoded.
  • Authorization: Basic, this should be a base64 encoded version of the string YOUR_DESCOPE_PROJECT_ID:.

Body:

  • grant_type: refresh_token.
  • refresh_token: This is the refresh token generated from the initial token exchange.

This API call should be set up to run by the On Page Load trigger and will use the refresh token from the currently authenticated user. After receiving the API response, it should be handled like in Step 6. The new token values should then be passed into the Update Authenticated User action.

Flutterflow actions for refreshing token

Was this helpful?

On this page