Aller au contenu principal

Personnaliser le FlutterFlow CustomAuthManager en utilisant le Logto SDK

FlutterFlow dispose d'une fonctionnalité intégrée de custom authentication qui vous permet d'authentifier les utilisateurs en utilisant votre propre backend. Cependant, le flux d'authentification personnalisé intégré a été conçu pour fonctionner avec un seul appel API d'authentification. Si vous utilisez un fournisseur d'identité tiers (IdP), la requête d’authentification ne peut être effectuée qu'en utilisant le type de subvention Resource Owner Password Credentials, ce qui n'est pas recommandé pour une utilisation en production. Voir Deprecated ropc grant type pour plus de détails.

Un flux d'authentification OpenID Connect (OIDC) standard implique plusieurs étapes, telles que l'Autorisation (Authorization), l'échange de jetons et la récupération d'informations utilisateur. Pour implémenter un flux d'authentification OIDC standard avec un IdP comme Logto, vous devez personnaliser la classe CustomAuthManager dans FlutterFlow.

Ce tutoriel vous montrera comment personnaliser la classe CustomAuthManager dans FlutterFlow en utilisant le Logto Flutter SDK. Vous pouvez tirer parti du Logto SDK pour le flux d'authentification OIDC standard tout en conservant les avantages du constructeur d'interface utilisateur FlutterFlow.

astuce:
  • Le package Logto SDK est disponible sur pub.dev et le dépôt GitHub de Logto.
  • Le SDK est actuellement uniquement adapté aux plateformes Android et iOS.

Prérequis

Activer le code personnalisé FlutterFlow

Pour personnaliser la classe CustomAuthManager, vous devez activer la fonctionnalité de code personnalisé dans FlutterFlow. Suivez le guide Manage Custom Code In GitHub pour synchroniser votre projet FlutterFlow avec GitHub.

remarque:

Gérer le code personnalisé dans GitHub est une fonctionnalité premium dans FlutterFlow. Vous devez mettre à niveau votre FlutterFlow vers le plan pro pour activer cette fonctionnalité.

Une fois cela fait, vous aurez trois branches différentes sous votre dépôt GitHub FlutterFlow :

  1. main : La branche principale pour le projet flutter. Vous aurez besoin de cette branche pour déployer votre projet.
  2. flutterflow : La branche où le FlutterFlow synchronisera les modifications depuis l'éditeur FlutterFlow.
  3. develop : La branche où vous pouvez modifier votre code personnalisé.

Créez votre interface utilisateur dans FlutterFlow

Tout d'abord, créez votre interface utilisateur dans FlutterFlow. Vous pouvez suivre la documentation FlutterFlow pour créer votre interface utilisateur en fonction de vos besoins. Pour ce tutoriel, pour le minimum requis, nous créerons deux pages :

  1. Une page d'accueil simple avec un bouton de connexion.
  2. Une page de profil utilisateur pour afficher les informations utilisateur et le bouton de déconnexion.

Allez à la page App Settings -> Authentication et activez l'authentification personnalisée. Cela créera une classe CustomAuthManager dans votre projet FlutterFlow.

FlutterFlow custom authentication

Une fois que vous avez l'interface utilisateur prête, naviguez vers la page integrations -> GitHub et cliquez sur le bouton Push to Repository pour pousser les modifications vers la branche flutterflow.

FlutterFlow GitHub push

Personnaliser le CustomAuthManager

Passez à la branche develop dans votre dépôt GitHub et fusionnez les dernières modifications de la branche flutterflow. Y compris vos pages d'interface utilisateur et la classe CustomAuthManager pré-construite.

Installer la dépendance Logto SDK

Ajoutez la dépendance Logto SDK à votre projet.

  flutter pub add logto_dart_sdk
remarque:

Package Http optionnel :

Le client Logto nécessite un client http pour effectuer des appels API. Vous pouvez utiliser le package http ou tout autre package client http de votre choix.

  flutter pub add http

Mettre à jour le UserProvider

Ajoutez la classe OpenIdClaims à la classe CustomAuthUserProvider pour stocker les informations utilisateur.

La classe OpenIdClaims fait partie du Logto SDK, qui fournira les revendications id_token pour l'utilisateur authentifié.

// lib/auth/custom_auth/custom_auth_user_provider.dart

import 'package:logto_dart_sdk/src/modules/id_token.dart';
import 'package:rxdart/rxdart.dart';

import 'custom_auth_manager.dart';

class FlutterFlowAuthAuthUser {
FlutterFlowAuthAuthUser({required this.loggedIn, this.uid, this.idToken});

bool loggedIn;
String? uid;
OpenIdClaims? idToken;
}

/// Génère un flux de l'utilisateur authentifié.
BehaviorSubject<FlutterFlowAuthAuthUser> flutterFlowAuthAuthUserSubject =
BehaviorSubject.seeded(FlutterFlowAuthAuthUser(loggedIn: false));
Stream<FlutterFlowAuthAuthUser> flutterFlowAuthAuthUserStream() =>
flutterFlowAuthAuthUserSubject
.asBroadcastStream()
.map((user) => currentUser = user);

Initialiser le client logto dans CustomAuthManager

Initialisez le client Logto dans la classe CustomAuthManager.

// lib/auth/custom_auth/custom_auth_manager.dart

import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:logto_dart_sdk/logto_client.dart';
import 'package:logto_dart_sdk/src/modules/id_token.dart';

import 'custom_auth_user_provider.dart';

export 'custom_auth_manager.dart';


class CustomAuthManager {
late LogtoClient logtoClient;

final logtoConfig = const LogtoConfig(
appId: '<YOUR-APP-ID>',
endpoint: '<YOUR-LOGTO-ENDPOINT>');


// ...

FlutterFlowAuthAuthUser? _updateCurrentUser(
{bool loggedIn = false, String? uid, OpenIdClaims? idToken}) {
// Mettre à jour le flux de l'utilisateur actuel.
final updatedUser = FlutterFlowAuthAuthUser(
loggedIn: loggedIn,
uid: uid,
idToken: idToken,
);

flutterFlowAuthAuthUserSubject.add(updatedUser);

return updatedUser;
}

Future initialize() async {
logtoClient = LogtoClient(config: logtoConfig, httpClient: http.Client());

late OpenIdClaims? idToken;

try {
idToken = await logtoClient.idTokenClaims;
} catch (e) {
if (kDebugMode) {
print('Erreur lors de l\'initialisation de l\'authentification : $e');
}
}

_updateCurrentUser(
loggedIn: idToken != null, uid: idToken?.subject, idToken: idToken);
}
}

FlutterFlowAuthAuthUser? currentUser;
bool get loggedIn => currentUser?.loggedIn ?? false;

La méthode initialize initialisera le client Logto et mettra à jour le flux utilisateur actuel avec le statut d'authentification utilisateur persistant dans le stockage local.

Le Logto SDK utilise le package flutter_secure_storage pour stocker les informations d'authentification utilisateur en toute sécurité.

Implémenter la méthode de connexion

Appeler la méthode LogtoClient.signIn initiera un flux d'authentification OIDC standard. La page de connexion Logto sera ouverte dans une webview en utilisant flutter_web_auth.

// lib/auth/custom_auth/custom_auth_manager.dart

Future<FlutterFlowAuthAuthUser?> signIn(
String redirectUri,
) async {
await logtoClient.signIn(redirectUri);

var idTokenClaims = await logtoClient.idTokenClaims;

return _updateCurrentUser(
loggedIn: idTokenClaims != null,
uid: idTokenClaims?.subject,
idToken: idTokenClaims,
);
}

LogtoClient gérera les étapes d'Autorisation (Authorization), d'échange de jetons et de récupération d'informations utilisateur. Une fois l'utilisateur authentifié, les idTokenClaims seront stockées dans le stockage local. Récupérez les idTokenClaims du LogtoClient et mettez à jour le flux utilisateur actuel.

Implémenter la méthode de déconnexion

// lib/auth/custom_auth/custom_auth_manager.dart

Future signOut() async {
await logtoClient.signOut();

flutterFlowAuthAuthUserSubject.add(
FlutterFlowAuthAuthUser(loggedIn: false),
);
}

Mettre à jour les méthodes utilitaires d'authentification

  • Ajoutez le getter authManager pour accéder à l'instance CustomAuthManager.
  • Ajoutez le getter currentUserUid pour obtenir l'uid de l'utilisateur actuel.
  • Ajoutez le getter currentUserData pour obtenir les données de l'utilisateur actuel.
  • Ajoutez le getter logtoClient pour accéder à l'instance du client Logto.
// lib/auth/custom_auth/auth_util.dart

import 'package:logto_dart_sdk/logto_client.dart';
import 'package:logto_dart_sdk/src/modules/id_token.dart';

import 'custom_auth_manager.dart';

export 'custom_auth_manager.dart';

final _authManager = CustomAuthManager();
CustomAuthManager get authManager => _authManager;
String get currentUserUid => currentUser?.uid ?? '';
OpenIdClaims? get currentUserData => currentUser?.idToken;
LogtoClient get logtoClient => _authManager.logtoClient;

Intégrer l'authentification personnalisée dans votre interface utilisateur

Page d'accueil

Appelez la méthode authManager.signIn pour initier le flux d'authentification lorsque l'utilisateur clique sur le bouton de connexion.

redirectUri est l'URL de rappel qui sera utilisée pour capturer le rappel d'autorisation depuis la page de connexion Logto. Voir le Flutter SDK pour plus de détails sur le redirectUri.

// lib/pages/home_page/home_page_widget.dart

final redirectUri = 'io.logto://callback';

// ...

FFButtonWidget(
onPressed: () async {
GoRouter.of(context).prepareAuthEvent();

await authManager.signIn(redirectUri);

context.replaceNamed('user');
},
text: 'Sign In',
// ...
)

Page de profil utilisateur

Utilisez les getters utilitaires d'authentification pour accéder aux données de l'utilisateur actuel et à l'instance du client Logto.

// lib/pages/user/user_widget.dart

import '/auth/custom_auth/auth_util.dart';

// ...

children: [
Text(
'User ID: $currentUserUid',
),
Text(
'Display Name: ${currentUserData?.name}',
),
Text(
'Username: ${currentUserData?.username}',
),
Text(
'Email: ${currentUserData?.emailVerified ?? currentUserData?.email}',
),
]

Implémentez la méthode de déconnexion lorsque l'utilisateur clique sur le bouton de déconnexion.

// lib/pages/user/user_widget.dart

FFButtonWidget(
onPressed: () async {
await authManager.signOut();

context.replaceNamed('HomePage');
},
text: 'Sign Out',
// ...
)

Lectures complémentaires

Le Logto SDK fournit plus de méthodes pour interagir avec l'API Logto. Vous pouvez personnaliser davantage la classe CustomAuthManager pour implémenter plus de fonctionnalités.

Dépannage des dépendances

flutter_secure_storage

Nous utilisons flutter_secure_storage pour implémenter le stockage sécurisé persistant de jetons multiplateforme. Sous le capot :

  • Keychain est utilisé pour iOS
  • Le chiffrement AES est utilisé pour Android.

Configurer la version Android :

Dans [project]/android/app/build.gradle, définissez minSdkVersion sur >= 18.

  android {
...

defaultConfig {
...
minSdkVersion 18
...
}
}

Désactiver la sauvegarde automatique :

remarque:

Par défaut, Android sauvegarde les données sur Google Drive. Cela peut provoquer l'exception java.security.InvalidKeyException:Failed to unwrap key.

Pour éviter cela, vous pouvez désactiver la sauvegarde automatique pour votre application ou exclure sharedprefs de FlutterSecureStorage.

  1. Pour désactiver la sauvegarde automatique, allez dans le fichier manifeste de votre application et définissez la valeur booléenne android:allowBackup :

    <manifest ... >
    ...
    <application
    android:allowBackup="false"
    android:fullBackupContent="false"
    ...
    >
    ...
    </application>
    </manifest>

  2. Exclure sharedprefs de FlutterSecureStorage.

    Si vous devez activer android:fullBackupContent pour votre application. Configurez une règle de sauvegarde pour exclure les prefs utilisées par le plugin :

    <application ...
    android:fullBackupContent="@xml/backup_rules">
    </application>
    <?xml version="1.0" encoding="utf-8"?>
    <full-backup-content>
    <exclude domain="sharedpref" path="FlutterSecureStorage"/>
    </full-backup-content>

    Veuillez consulter flutter_secure_storage pour plus de détails.

flutter_web_auth

flutter_web_auth est utilisé derrière le SDK flutter de Logto. Nous nous appuyons sur son interface d'interaction basée sur webview pour ouvrir les pages d'Autorisation (Authorization) de Logto.

remarque:

Ce plugin utilise ASWebAuthenticationSession sur iOS 12+ et macOS 10.15+, SFAuthenticationSession sur iOS 11, Chrome Custom Tabs sur Android et ouvre une nouvelle fenêtre sur le Web. Vous pouvez le construire avec iOS 8+, mais il est actuellement uniquement pris en charge par iOS 11 ou supérieur.

Enregistrer l'URL de rappel sur Android

Afin de capturer l'URL de rappel depuis la page de connexion de Logto, vous devrez enregistrer votre redirectUri de connexion dans le fichier AndroidManifest.xml.

<activity android:name="com.linusu.flutter_web_auth.CallbackActivity" android:exported="true">
<intent-filter android:label="flutter_web_auth">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="io.logto"/>
</intent-filter>
</activity>