Zum Hauptinhalt springen

Authentifizierung zu deiner Flutter-Anwendung hinzufügen

Dieses Tutorial zeigt dir, wie du Logto in deine Flutter-Anwendung integrieren kannst.

tipp:
  • Das SDK-Paket ist verfügbar auf pub.dev und im Logto GitHub-Repository.
  • Das Beispielprojekt wurde mit Flutter Material erstellt. Du findest es auf pub.dev.
  • Dieses SDK ist kompatibel mit Flutter-Anwendungen auf iOS-, Android- und Web-Plattformen. Die Kompatibilität mit anderen Plattformen wurde nicht getestet.

Voraussetzungen

Installation

Du kannst das logto_dart_sdk package direkt mit dem Pub-Paketmanager installieren. Führe den folgenden Befehl im Stammverzeichnis deines Projekts aus:

flutter pub add logto_dart_sdk

Oder füge das Folgende zu deiner pubspec.yaml Datei hinzu:

dependencies:
logto_dart_sdk: ^3.0.0

Dann führe aus:

flutter pub get

Einrichtung

SDK-Version-Kompatibilität

Logto SDK-VersionDart SDK-VersionDart 3.0 kompatibel
< 2.0.0>= 2.17.6 < 3.0.0false
>= 2.0.0 < 3.0.0>= 3.0.0true
>= 3.0.0>= 3.6.0true

flutter_secure_storage Einrichtung

Im Hintergrund verwendet dieses SDK flutter_secure_storage, um die plattformübergreifende, persistente sichere Token-Speicherung zu implementieren.

  • Keychain wird für iOS verwendet
  • AES-Verschlüsselung wird für Android verwendet.

Android-Version konfigurieren

Setze die android:minSdkVersion auf >= 18 in der android/app/build.gradle-Datei deines Projekts.

build.gradle
  android {
...

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

Automatisches Backup auf Android deaktivieren

Standardmäßig sichert Android Daten auf Google Drive. Dies kann die Ausnahme java.security.InvalidKeyException:Failed verursachen, um den Schlüssel zu entpacken. Um dies zu vermeiden,

  1. Um das automatische Backup zu deaktivieren, gehe zu deiner App-Manifest-Datei und setze die Attribute android:allowBackup und android:fullBackupContent auf false.

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

  2. Schließe sharedprefs von FlutterSecureStorage aus.

    Wenn du android:fullBackupContent für deine App beibehalten musst, anstatt es zu deaktivieren, kannst du das sharedprefs-Verzeichnis vom Backup ausschließen. Siehe weitere Details in der Android-Dokumentation.

    In deiner AndroidManifest.xml-Datei füge das Attribut android:fullBackupContent zum <application>-Element hinzu, wie im folgenden Beispiel gezeigt. Dieses Attribut verweist auf eine XML-Datei, die Backup-Regeln enthält.

    AndroidManifest.xml
    <application ...
    android:fullBackupContent="@xml/backup_rules">
    </application>

    Erstelle eine XML-Datei namens @xml/backup_rules im Verzeichnis res/xml/. In dieser Datei füge Regeln mit den Elementen <include> und <exclude> hinzu. Das folgende Beispiel sichert alle Shared Preferences außer device.xml:

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

Bitte überprüfe flutter_secure_storage für weitere Details.

flutter_web_auth_2 Einrichtung

Im Hintergrund verwendet dieses SDK flutter_web_auth_2, um Benutzer mit Logto zu authentifizieren. Dieses Paket bietet eine einfache Möglichkeit, Benutzer mit Logto über das System-Webview oder den Browser zu authentifizieren.

Dieses Plugin verwendet ASWebAuthenticationSession auf iOS 12+ und macOS 10.15+, SFAuthenticationSession auf iOS 11, Chrome Custom Tabs auf Android und öffnet ein neues Fenster im Web.

  • iOS: Keine zusätzliche Einrichtung erforderlich

  • Android: Registriere die Callback-URL auf Android

    Um die Callback-URL von Logtos Anmelde-Webseite zu erfassen, musst du deine Anmelde-redirectUri in deiner AndroidManifest.xml-Datei registrieren.

    AndroidManifest.xml
      <manifest>
    <application>
    <activity
    android:name="com.linusu.flutter_web_auth_2.CallbackActivity"
    android:exported="true">
    <intent-filter android:label="flutter_web_auth_2">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="YOUR_CALLBACK_URL_SCHEME_HERE" />
    </intent-filter>
    </activity>
    </application>
    </manifest>
  • Webbrowser: Erstelle einen Endpunkt, um die Callback-URL zu verarbeiten

    Wenn du die Webplattform verwendest, musst du einen Endpunkt erstellen, um die Callback-URL zu verarbeiten und sie mit der postMessage-API an die Anwendung zurückzusenden.

    callback.html
    <!doctype html>
    <title>Authentifizierung abgeschlossen</title>
    <p>
    Die Authentifizierung ist abgeschlossen. Falls dies nicht automatisch geschieht, bitte das
    Fenster schließen.
    </p>
    <script>
    function postAuthenticationMessage() {
    const message = {
    'flutter-web-auth-2': window.location.href,
    };

    if (window.opener) {
    window.opener.postMessage(message, window.location.origin);
    window.close();
    } else if (window.parent && window.parent !== window) {
    window.parent.postMessage(message, window.location.origin);
    } else {
    localStorage.setItem('flutter-web-auth-2', window.location.href);
    window.close();
    }
    }

    postAuthenticationMessage();
    </script>

Bitte überprüfe die Einrichtungshinweise im flutter_web_auth_2 Paket für weitere Details.

Integration

LogtoClient initialisieren

Importiere das logto_dart_sdk Paket und initialisiere die LogtoClient Instanz am Root deiner Anwendung.

lib/main.dart
import 'package:logto_dart_sdk/logto_dart_sdk.dart';
import 'package:http/http.dart' as http;

void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);


Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(title: 'Logto Demo Home Page'),
);
}
}

class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;


State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
late LogtoClient logtoClient;

void render() {
// Zustandsänderung
}

// LogtoConfig
final logtoConfig = const LogtoConfig(
endpoint: "<your-logto-endpoint>",
appId: "<your-app-id>"
);

void _init() {
logtoClient = LogtoClient(
config: logtoConfig,
httpClient: http.Client(), // Optionaler HTTP-Client
);
render();
}


void initState() {
super.initState();
_init();
}

// ...
}

Anmeldung implementieren

Bevor wir in die Details eintauchen, hier ein kurzer Überblick über die Endbenutzererfahrung. Der Anmeldeprozess kann wie folgt vereinfacht werden:

  1. Deine App ruft die Anmeldemethode auf.
  2. Der Benutzer wird zur Logto-Anmeldeseite umgeleitet. Bei nativen Apps wird der Systembrowser geöffnet.
  3. Der Benutzer meldet sich an und wird zurück zu deiner App umgeleitet (konfiguriert als die Redirect-URI).

Bezüglich der umleitungsbasierten Anmeldung

  1. Dieser Authentifizierungsprozess folgt dem OpenID Connect (OIDC) Protokoll, und Logto erzwingt strenge Sicherheitsmaßnahmen, um die Benutzeranmeldung zu schützen.
  2. Wenn du mehrere Apps hast, kannst du denselben Identitätsanbieter (Logto) verwenden. Sobald sich der Benutzer bei einer App anmeldet, wird Logto den Anmeldeprozess automatisch abschließen, wenn der Benutzer auf eine andere App zugreift.

Um mehr über die Gründe und Vorteile der umleitungsbasierten Anmeldung zu erfahren, siehe Logto-Anmeldeerfahrung erklärt.


Bevor du beginnst, musst du eine Redirect-URI in der Admin-Konsole für deine Anwendung hinzufügen.

Wechseln wir zur Seite "Anwendungsdetails" der Logto-Konsole. Füge eine Redirect-URI io.logto://callback hinzu und klicke auf "Änderungen speichern".

Redirect-URI in Logto-Konsole
  • Für iOS spielt das Redirect-URI-Schema keine Rolle, da die ASWebAuthenticationSession Klasse auf die Redirect-URI hört, unabhängig davon, ob sie registriert ist.
  • Für Android muss das Redirect-URI-Schema in der AndroidManifest.xml Datei registriert werden.

Nachdem die Redirect-URI konfiguriert ist, fügen wir deiner Seite einen Anmeldebutton hinzu, der die logtoClient.signIn API aufruft, um den Logto-Anmeldefluss zu starten:

lib/main.dart
class _MyHomePageState extends State<MyHomePage> {
// ...
final redirectUri = 'io.logto://callback';


Widget build(BuildContext context) {
// ...

Widget signInButton = TextButton(
onPressed: () async {
await logtoClient.signIn(redirectUri);
render();
},
child: const Text('Sign In'),
);

return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SelectableText('My Demo App'),
signInButton,
],
),
),
);
}
}

Abmeldung implementieren

Wechseln wir zur Seite mit den Anwendungsdetails der Logto-Konsole. Füge eine Post Sign-out Redirect URI io.logto://callback hinzu und klicke auf „Änderungen speichern“.

Post Sign-out Redirect URI in Logto Console

Post Sign-out Redirect URI ist ein OAuth 2.0-Konzept, das impliziert, wohin nach dem Abmelden umgeleitet werden soll.

Fügen wir nun auf der Hauptseite einen Abmeldebutton hinzu, damit sich Benutzer von deiner Anwendung abmelden können.

lib/main.dart
class _MyHomePageState extends State<MyHomePage> {
// ...

final postSignOutRedirectUri = 'io.logto//home';


Widget build(BuildContext context) {
// ...

Widget signOutButton = TextButton(
onPressed: () async {
await logtoClient.signOut(postSignOutRedirectUri);
render();
},
child: const Text('Sign Out'),
);

return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SelectableText('My Demo App'),
signInButton,
signOutButton,
],
),
),
);
}
}

Authentifizierungsstatus verwalten

Das Logto SDK bietet eine asynchrone Methode, um den Authentifizierungsstatus zu überprüfen. Die Methode ist logtoClient.isAuthenticated. Die Methode gibt einen booleschen Wert zurück, true, wenn der Benutzer authentifiziert ist, andernfalls false.

Im Beispiel rendern wir die Anmelde- und Abmeldebuttons bedingt basierend auf dem Authentifizierungsstatus. Aktualisieren wir nun die render Methode in unserem Widget, um die Zustandsänderung zu verwalten:

lib/main.dart
class _MyHomePageState extends State<MyHomePage> {
// ...
bool? isAuthenticated = false;

void render() {
setState(() async {
isAuthenticated = await logtoClient.isAuthenticated;
});
}


Widget build(BuildContext context) {
// ...

return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SelectableText('My Demo App'),
isAuthenticated == true ? signOutButton : signInButton,
],
),
),
);
}
}

Checkpoint: Teste deine Anwendung

Jetzt kannst du deine Anwendung testen:

  1. Starte deine Anwendung, du wirst den Anmeldebutton sehen.
  2. Klicke auf den Anmeldebutton, das SDK wird den Anmeldeprozess initiieren und dich zur Logto-Anmeldeseite weiterleiten.
  3. Nachdem du dich angemeldet hast, wirst du zurück zu deiner Anwendung geleitet und siehst den Abmeldebutton.
  4. Klicke auf den Abmeldebutton, um den Token-Speicher zu leeren und dich abzumelden.

Benutzerinformationen abrufen

Benutzerinformationen anzeigen

Um die Informationen des Benutzers anzuzeigen, kannst du den logtoClient.idTokenClaims Getter verwenden. Zum Beispiel in einer Flutter-App:

lib/main.dart
class _MyHomePageState extends State<MyHomePage> {
// ...


Widget build(BuildContext context) {
// ...

Widget getUserInfoButton = TextButton(
onPressed: () async {
final userClaims = await logtoClient.idTokenClaims;
print(userInfo);
},
child: const Text('Benutzerinformationen abrufen'),
);

return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SelectableText('Meine Demo-App'),
isAuthenticated == true ? signOutButton : signInButton,
isAuthenticated == true ? getUserInfoButton : const SizedBox.shrink(),
],
),
),
);
}
}

Zusätzliche Ansprüche anfordern

Möglicherweise fehlen einige Benutzerinformationen im zurückgegebenen Objekt von client.idTokenClaims. Dies liegt daran, dass OAuth 2.0 und OpenID Connect (OIDC) so konzipiert sind, dass sie dem Prinzip der minimalen Rechte (PoLP) folgen, und Logto auf diesen Standards basiert.

Standardmäßig werden begrenzte Ansprüche zurückgegeben. Wenn du mehr Informationen benötigst, kannst du zusätzliche Berechtigungen anfordern, um auf mehr Ansprüche zuzugreifen.

info:

Ein "Anspruch (Claim)" ist eine Behauptung über ein Subjekt; eine "Berechtigung (Scope)" ist eine Gruppe von Ansprüchen. Im aktuellen Fall ist ein Anspruch ein Informationsstück über den Benutzer.

Hier ist ein nicht-normatives Beispiel für die Beziehung zwischen Berechtigung und Anspruch:

tipp:

Der "sub"-Anspruch bedeutet "Subjekt", was der eindeutige Identifikator des Benutzers ist (d. h. Benutzer-ID).

Das Logto SDK wird immer drei Berechtigungen anfordern: openid, profile und offline_access.

Um zusätzliche Berechtigungen anzufordern, kannst du die Berechtigungen an das LogtoConfig Objekt übergeben. Zum Beispiel:

lib/main.dart
// LogtoConfig
final logtoConfig = const LogtoConfig(
endpoint: "<your-logto-endpoint>",
appId: "<your-app-id>",
scopes: ["email", "phone"],
);

Wir bieten auch ein eingebautes LogtoUserScope-Enum im SDK-Paket an, um dir bei der Verwendung der vordefinierten Berechtigungen zu helfen.

// LogtoConfig
final logtoConfig = const LogtoConfig(
endpoint: "<your-logto-endpoint>",
appId: "<your-app-id>",
scopes: [LogtoUserScope.email.value, LogtoUserScope.phone.value],
);

Ansprüche, die Netzwerk-Anfragen benötigen

Um das ID-Token nicht aufzublähen, erfordern einige Ansprüche Netzwerk-Anfragen, um abgerufen zu werden. Zum Beispiel ist der custom_data Anspruch nicht im Benutzerobjekt enthalten, selbst wenn er in den Berechtigungen angefordert wird. Um auf diese Ansprüche zuzugreifen, kannst du die logtoClient.getUserInfo() Methode verwenden:

lib/main.dart
class _MyHomePageState extends State<MyHomePage> {
// ...


Widget build(BuildContext context) {
// ...

Widget getUserInfoButton = TextButton(
onPressed: () async {
final userInfo = await logtoClient.getUserInfo();
print(userInfo);
},
child: const Text('Benutzerinformationen abrufen'),
);

return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SelectableText('Meine Demo-App'),
isAuthenticated == true ? signOutButton : signInButton,
isAuthenticated == true ? getUserInfoButton : const SizedBox.shrink(),
],
),
),
);
}
}
Diese Methode wird die Benutzerinformationen abrufen, indem sie eine Anfrage an den Userinfo-Endpunkt stellt. Um mehr über die verfügbaren Berechtigungen und Ansprüche zu erfahren, siehe den Berechtigungen und Ansprüche Abschnitt.

Berechtigungen und Ansprüche

Logto verwendet OIDC Berechtigungen und Ansprüche Konventionen, um die Berechtigungen und Ansprüche für das Abrufen von Benutzerinformationen aus dem ID-Token und dem OIDC userinfo endpoint zu definieren. Sowohl "Berechtigung (Scope)" als auch "Anspruch (Claim)" sind Begriffe aus den OAuth 2.0 und OpenID Connect (OIDC) Spezifikationen.

Hier ist die Liste der unterstützten Berechtigungen (Scopes) und der entsprechenden Ansprüche (Claims):

openid

AnspruchsnameTypBeschreibungBenötigt userinfo?
substringDer eindeutige Identifikator des BenutzersNein

profile

AnspruchsnameTypBeschreibungBenötigt userinfo?
namestringDer vollständige Name des BenutzersNein
usernamestringDer Benutzername des BenutzersNein
picturestringURL des Profilbildes des Endbenutzers. Diese URL MUSS auf eine Bilddatei (zum Beispiel eine PNG-, JPEG- oder GIF-Bilddatei) verweisen, anstatt auf eine Webseite, die ein Bild enthält. Beachte, dass diese URL speziell auf ein Profilfoto des Endbenutzers verweisen SOLLTE, das geeignet ist, den Endbenutzer zu beschreiben, anstatt auf ein beliebiges vom Endbenutzer aufgenommenes Foto.Nein
created_atnumberZeitpunkt, zu dem der Endbenutzer erstellt wurde. Die Zeit wird als Anzahl der Millisekunden seit dem Unix-Epoch (1970-01-01T00:00:00Z) dargestellt.Nein
updated_atnumberZeitpunkt, zu dem die Informationen des Endbenutzers zuletzt aktualisiert wurden. Die Zeit wird als Anzahl der Millisekunden seit dem Unix-Epoch (1970-01-01T00:00:00Z) dargestellt.Nein

Andere Standardansprüche wie family_name, given_name, middle_name, nickname, preferred_username, profile, website, gender, birthdate, zoneinfo und locale werden ebenfalls im profile-Scope enthalten sein, ohne dass der userinfo-Endpunkt angefordert werden muss. Ein Unterschied im Vergleich zu den obigen Ansprüchen besteht darin, dass diese Ansprüche nur zurückgegeben werden, wenn ihre Werte nicht leer sind, während die obigen Ansprüche null zurückgeben, wenn die Werte leer sind.

hinweis:

Im Gegensatz zu den Standardansprüchen verwenden die Ansprüche created_at und updated_at Millisekunden anstelle von Sekunden.

email

AnspruchsnameTypBeschreibungBenötigt userinfo?
emailstringDie E-Mail-Adresse des BenutzersNein
email_verifiedbooleanOb die E-Mail-Adresse verifiziert wurdeNein

phone

AnspruchsnameTypBeschreibungBenötigt userinfo?
phone_numberstringDie Telefonnummer des BenutzersNein
phone_number_verifiedbooleanOb die Telefonnummer verifiziert wurdeNein

address

Bitte siehe OpenID Connect Core 1.0 für die Details des Adressanspruchs.

custom_data

AnspruchsnameTypBeschreibungBenötigt userinfo?
custom_dataobjectDie benutzerdefinierten Daten des BenutzersJa

identities

AnspruchsnameTypBeschreibungBenötigt userinfo?
identitiesobjectDie verknüpften Identitäten des BenutzersJa
sso_identitiesarrayDie verknüpften SSO-Identitäten des BenutzersJa

roles

AnspruchsnameTypBeschreibungBenötigt userinfo?
rolesstring[]Die Rollen des BenutzersNein

urn:logto:scope:organizations

AnspruchsnameTypBeschreibungBenötigt userinfo?
organizationsstring[]Die Organisations-IDs, denen der Benutzer angehörtNein
organization_dataobject[]Die Organisationsdaten, denen der Benutzer angehörtJa

urn:logto:scope:organization_roles

AnspruchsnameTypBeschreibungBenötigt userinfo?
organization_rolesstring[]Die Organisationsrollen, denen der Benutzer angehört, im Format <organization_id>:<role_name>Nein

In Anbetracht der Leistung und der Datengröße bedeutet "Benötigt userinfo?" "Ja", dass der Anspruch nicht im ID-Token angezeigt wird, sondern in der Antwort des userinfo-Endpunkts zurückgegeben wird.

API-Ressourcen und Organisationen

Wir empfehlen, zuerst 🔐 Rollenbasierte Zugangskontrolle (RBAC) zu lesen, um die grundlegenden Konzepte von Logto RBAC zu verstehen und wie man API-Ressourcen richtig einrichtet.

Logto-Client konfigurieren

Sobald du die API-Ressourcen eingerichtet hast, kannst du sie bei der Konfiguration von Logto in deiner App hinzufügen:

lib/main.dart
// LogtoConfig
final logtoConfig = const LogtoConfig(
endpoint: "<your-logto-endpoint>",
appId: "<your-app-id>",
// Füge deine API-Ressourcen hinzu
resources: ["https://shopping.your-app.com/api", "https://store.your-app.com/api"],
);

Jede API-Ressource hat ihre eigenen Berechtigungen (Berechtigungen).

Zum Beispiel hat die Ressource https://shopping.your-app.com/api die Berechtigungen shopping:read und shopping:write, und die Ressource https://store.your-app.com/api hat die Berechtigungen store:read und store:write.

Um diese Berechtigungen anzufordern, kannst du sie bei der Konfiguration von Logto in deiner App hinzufügen:

lib/main.dart
// LogtoConfig
final logtoConfig = const LogtoConfig(
endpoint: "<your-logto-endpoint>",
appId: "<your-app-id>",
resources: ["https://shopping.your-app.com/api", "https://store.your-app.com/api"],
// Add your API resources' scopes
scopes: ["shopping:read", "shopping:write", "store:read", "store:write"]
);

Du wirst bemerken, dass Berechtigungen separat von API-Ressourcen definiert sind. Dies liegt daran, dass Resource Indicators for OAuth 2.0 spezifiziert, dass die endgültigen Berechtigungen für die Anfrage das kartesische Produkt aller Berechtigungen bei allen Zielservices sein werden.

Somit können im obigen Fall die Berechtigungen aus der Definition in Logto vereinfacht werden, beide API-Ressourcen können read und write Berechtigungen ohne Präfix haben. Dann, in der Logto-Konfiguration:

lib/main.dart
// LogtoConfig
final logtoConfig = const LogtoConfig(
endpoint: "<your-logto-endpoint>",
appId: "<your-app-id>",
resources: ["https://shopping.your-app.com/api", "https://store.your-app.com/api"],
// Gemeinsame Berechtigungen für alle Ressourcen
scopes: ["read", "write"]
);

Für jede API-Ressource wird sowohl read als auch write Berechtigungen angefordert.

hinweis:

Es ist in Ordnung, Berechtigungen anzufordern, die in den API-Ressourcen nicht definiert sind. Zum Beispiel kannst du die Berechtigung email anfordern, auch wenn die API-Ressourcen die Berechtigung email nicht verfügbar haben. Nicht verfügbare Berechtigungen werden sicher ignoriert.

Nach der erfolgreichen Anmeldung wird Logto die entsprechenden Berechtigungen an API-Ressourcen gemäß den Rollen des Benutzers ausstellen.

Zugangstoken für die API-Ressource abrufen

Um das Zugangstoken für eine spezifische API-Ressource abzurufen, kannst du die Methode getAccessToken verwenden:

lib/main.dart
Future<AccessToken?> getAccessToken(String resource) async {
var token = await logtoClient.getAccessToken(resource: resource);

return token;
}

Diese Methode gibt ein JWT-Zugangstoken zurück, das verwendet werden kann, um auf die API-Ressource zuzugreifen, wenn der Benutzer die entsprechenden Berechtigungen hat. Wenn das aktuell zwischengespeicherte Zugangstoken abgelaufen ist, versucht diese Methode automatisch, ein Auffrischungstoken zu verwenden, um ein neues Zugangstoken zu erhalten.

Zugangstoken für Organisationen abrufen

Genau wie bei API-Ressourcen kannst du auch ein Zugangstoken für Organisationen anfordern. Dies ist nützlich, wenn du auf Ressourcen zugreifen musst, die mit der Organisations-Berechtigung anstelle der API-Ressourcen-Berechtigung definiert sind.

Wenn Organisationen neu für dich sind, lies bitte 🏢 Organisationen (Multi-Tenancy), um loszulegen.

Du musst die Berechtigung LogtoUserScope.Organizations hinzufügen, wenn du den Logto-Client konfigurierst:

lib/main.dart
// LogtoConfig
final logtoConfig = const LogtoConfig(
endpoint: "<your-logto-endpoint>",
appId: "<your-app-id>",
scopes: [LogtoUserScopes.organizations.value]
);

Sobald der Benutzer angemeldet ist, kannst du das Organisationstoken für den Benutzer abrufen:

// Gültige Organisations-IDs für den Benutzer sind im ID-Token-Anspruch `organizations` zu finden.
Future<AccessToken?> getOrganizationAccessToken(String organizationId) async {
var token = await logtoClient.getOrganizationToken(organizationId);

return token;
}

Migrationsleitfaden

Wenn du von einer früheren Version des Logto Dart SDK migrierst, Version < 3.0.0:

  1. Aktualisiere deine pubspec.yaml Datei, um die neueste Version des Logto Dart SDK zu verwenden.

    pubspec.yaml
    dependencies:
    logto_dart_sdk: ^3.0.0
  2. Aktualisiere die Android-Manifest-Datei, ersetze die veraltete flutter_web_auth Callback-Aktivität durch die neue flutter_web_auth_2.

    • FlutterWebAuth -> FlutterWebAuth2
    • flutter_web_auth -> flutter_web_auth_2
  3. Übergebe die redirectUri an die signOut Methode.

    redirectUri ist jetzt erforderlich, wenn die signOut Methode aufgerufen wird. Für die iOS-Plattform ist dieser Parameter nutzlos, aber für Android- und Web-Plattformen, die eine zusätzliche end_session Anfrage benötigen, um die Anmeldesitzung zu bereinigen, wird dieser Parameter als post_logout_redirect_uri Parameter in der end_session Anfrage verwendet.

    await logtoClient.signOut(redirectUri);

Fehlerbehebung

Fehlerbehebung Android

  • Du musst deine AndroidManifest.xml aktualisieren, um die com.linusu.flutter_web_auth_2.CallbackActivity Aktivität einzuschließen, etwa so:

    android/app/src/main/AndroidManifest.xml
      <manifest>
    <application>

    <!-- füge die com.linusu.flutter_web_auth_2.CallbackActivity Aktivität hinzu -->
    <activity
    android:name="com.linusu.flutter_web_auth_2.CallbackActivity"
    android:exported="true">
    <intent-filter android:label="flutter_web_auth_2">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="YOUR_CALLBACK_URL_SCHEME_HERE" />
    </intent-filter>
    </activity>

    </application>
    </manifest>
  • Wenn du S+ (SDK-Version 31 und höher) anvisierst, musst du einen expliziten Wert für android:exported angeben. Wenn du den früheren Installationsanweisungen gefolgt bist, war dies nicht enthalten. Stelle sicher, dass du android:exported="true" zur com.linusu.flutter_web_auth.CallbackActivity Aktivität in deiner AndroidManifest.xml Datei hinzufügst.

  • Browser wird nach erfolgreicher Anmeldung nicht geschlossen:

    Um sicherzustellen, dass flutter_web_auth_2 korrekt funktioniert, musst du alle android:taskAffinity Einträge aus deiner AndroidManifest.xml Datei entfernen. Setze android:launchMode="singleTop" zur Hauptaktivität in deiner AndroidManifest.xml Datei.

    android/app/src/main/AndroidManifest.xml
    <activity
    android:name=".MainActivity"
    android:launchMode="singleTop"
    android:theme="@style/LaunchTheme"
    // ...
    />

Weiterführende Lektüre

Endbenutzerflüsse: Authentifizierungsflüsse, Kontoflüsse und Organisationsflüsse Connectors konfigurieren Schütze deine API