Logto SDK を使用して FlutterFlow CustomAuthManager をカスタマイズする
FlutterFlow には、独自のバックエンドを使用してユーザーを認証 (Authentication) できる カスタム認証 (Authentication) 機能が組み込まれています。ただし、組み込みのカスタム認証 (Authentication) フローは、単一の認証 (Authentication) API 呼び出しで動作するように設計されています。サードパーティのアイデンティティプロバイダー (IdP) を使用している場合、認証 (Authentication) リクエストは Resource Owner Password Credentials
グラントタイプを使用してのみ行うことができ、これは本番環境での使用には推奨されません。詳細については、廃止された ropc グラントタイプ を参照してください。
標準の OpenID Connect (OIDC) 認証 (Authentication) フローには、認可 (Authorization)、トークン交換、ユーザー情報の取得など、複数のステップが含まれます。Logto のような IdP を使用して標準の OIDC 認証 (Authentication) フローを実装するには、FlutterFlow の CustomAuthManager
クラスをカスタマイズする必要があります。
このチュートリアルでは、Logto Flutter SDK を使用して FlutterFlow の CustomAuthManager
クラスをカスタマイズする方法を示します。FlutterFlow UI ビルダーの利点を維持しながら、標準の OIDC 認証 (Authentication) フローのために Logto SDK を活用できます。
- Logto SDK パッケージは pub.dev と Logto GitHub リポジトリ で利用可能です。
- SDK は現在、Android および iOS プラットフォームにのみ適しています。
前提条件
- Logto Cloud アカウントまたは セルフホスト Logto。
- Logto Flutter アプリケーションを作成する。
- FlutterFlow プロジェクト。
FlutterFlow カスタムコードを有効にする
CustomAuthManager
クラスをカスタマイズするには、FlutterFlow でカスタムコード機能を有効にする必要があります。GitHub でカスタムコードを管理する ガイドに従って、FlutterFlow プロジェクトを GitHub と同期します。
GitHub でカスタムコードを管理することは、FlutterFlow のプレミアム機能です。この機能を有効にするには、FlutterFlow をプロプランにアップグレードする必要があります。
完了すると、GitHub FlutterFlow リポジトリに次の 3 つの異なるブランチが作成されます:
main
: Flutter プロジェクトのメインブランチ。このブランチを使用してプロジェクトをデプロイする必要があります。flutterflow
:FlutterFlow
が FlutterFlow エディターからの変更を同期するブランチ。develop
: カスタムコードを修正できるブランチ。
FlutterFlow で UI を作成する
まず、FlutterFlow で UI を作成します。要件に基づいて UI を作成するために FlutterFlow ドキュメント を参照できます。このチュートリアルでは、最低限の要件として次の 2 つのページを作成します:
- ログインボタンを備えたシンプルなホームページ。
- ユーザー情報を表示し、ログアウトボタンを備えたユーザープロファイルページ。
App Settings
-> Authentication
ページに移動し、カスタム認証 (Authentication) を有効にします。これにより、FlutterFlow プロジェクトに CustomAuthManager
クラスが作成されます。
UI が準備できたら、integrations
-> GitHub
ページに移動し、Push to Repository
ボタンをクリックして変更を flutterflow
ブランチにプッシュします。
CustomAuthManager をカスタマイズする
GitHub リポジトリで develop
ブランチに切り替え、flutterflow
ブランチから最新の変更をマージします。UI ページと、事前に構築された CustomAuthManager
クラスを含めます。
Logto SDK 依存関係をインストールする
プロジェクトに Logto SDK 依存関係を追加します。
flutter pub add logto_dart_sdk
オプションの Http パッケージ:
Logto クライアントは API 呼び出しを行うために http クライアントを必要とします。http
パッケージや他の任意の http クライアントパッケージを使用できます。
flutter pub add http
UserProvider を更新する
ユーザー情報を保存するために OpenIdClaims
クラスを CustomAuthUserProvider
クラスに追加します。
OpenIdClaims
クラスは Logto SDK の一部であり、認証 (Authentication) されたユーザーのid_token
クレームを提供します。
// 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;
}
/// 認証されたユーザーのストリームを生成します。
BehaviorSubject<FlutterFlowAuthAuthUser> flutterFlowAuthAuthUserSubject =
BehaviorSubject.seeded(FlutterFlowAuthAuthUser(loggedIn: false));
Stream<FlutterFlowAuthAuthUser> flutterFlowAuthAuthUserStream() =>
flutterFlowAuthAuthUserSubject
.asBroadcastStream()
.map((user) => currentUser = user);
CustomAuthManager で logto クライアントを初期化する
CustomAuthManager
クラスで Logto クライアントを初期化します。
// 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}) {
// 現在のユーザーストリームを更新します。
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('認証 (Authentication) の初期化中にエラーが発生しました: $e');
}
}
_updateCurrentUser(
loggedIn: idToken != null, uid: idToken?.subject, idToken: idToken);
}
}
FlutterFlowAuthAuthUser? currentUser;
bool get loggedIn => currentUser?.loggedIn ?? false;
initialize
メソッドは Logto クライアントを初期化し、ローカルストレージに保存されたユーザー認証 (Authentication) 状態で現在のユーザーストリームを更新します。
Logto SDK は flutter_secure_storage パッケージを使用して、ユーザー認証 (Authentication) 情報を安全に保存します。
サインインメソッドを実装する
LogtoClient.signIn
メソッドを呼び出すと、標準の OIDC 認証 (Authentication) フローが開始されます。Logto サインインページは flutter_web_auth を使用して WebView で開かれます。
// 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 は認可 (Authorization)、トークン交換、ユーザー情報の取得ステップを処理します。ユーザーが認証 (Authentication) されると、idTokenClaims
はローカルストレージに保存されます。
LogtoClient から idTokenClaims
を取得し、現在のユーザーストリームを更新します。
サインアウトメソッドを実装する
// lib/auth/custom_auth/custom_auth_manager.dart
Future signOut() async {
await logtoClient.signOut();
flutterFlowAuthAuthUserSubject.add(
FlutterFlowAuthAuthUser(loggedIn: false),
);
}
認証 (Authentication) ユーティリティメソッドを更新する
CustomAuthManager
インスタンスにアクセスするためのauthManager
ゲッターを追加します。- 現在のユーザー uid を取得するための
currentUserUid
ゲッターを追加します。 - 現在のユーザーデータを取得するための
currentUserData
ゲッターを追加します。 - Logto クライアントインスタンスにアクセスするための
logtoClient
ゲッターを追加します。
// 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;
UI にカスタム認証 (Authentication) を統合する
ホームページ
ユーザーがサインインボタンをクリックしたときに認証 (Authentication) フローを開始するために authManager.signIn
メソッドを呼び出します。
redirectUri
は、Logto サインインページからの認可 (Authorization) コールバックをキャプチャするために使用されるコールバック URL です。 redirectUri の詳細については、Flutter SDK を参照してください。
// 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',
// ...
)
ユーザープロファイルページ
現在のユーザーデータと Logto クライアントインスタンスにアクセスするために認証 (Authentication) ユーティリティゲッターを使用します。
// 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}',
),
]
ユーザーがサインアウトボタンをクリックしたときにサインアウトメソッドを実装します。
// lib/pages/user/user_widget.dart
FFButtonWidget(
onPressed: () async {
await authManager.signOut();
context.replaceNamed('HomePage');
},
text: 'Sign Out',
// ...
)
さらなる読み物
Logto SDK は Logto API と対話するためのより多くのメソッドを提供します。CustomAuthManager
クラスをさらにカスタマイズして、より多くの機能を実装することができます。
依存関係のトラブルシューティング
flutter_secure_storage
クロスプラットフォームの永続的なセキュアトークンストレージを実装するために、flutter_secure_storage を使用しています。内部では:
- iOS では Keychain が使用されます
- Android では AES 暗号化が使用されます。
Android バージョンの設定:
[project]/android/app/build.gradle で minSdkVersion を >= 18 に設定します。
android {
...
defaultConfig {
...
minSdkVersion 18
...
}
}
自動バックアップを無効にする:
デフォルトでは、Android は Google Drive にデータをバックアップします。これにより、例外 java.security.InvalidKeyException:Failed to unwrap key が発生する可能性があります。
これを避けるために、アプリの自動バックアップを無効にするか、FlutterSecureStorage から sharedprefs を除外することができます。
-
自動バックアップを無効にするには、アプリのマニフェストファイルに移動し、ブール値 android:allowBackup を設定します:
<manifest ... >
...
<application
android:allowBackup="false"
android:fullBackupContent="false"
...
>
...
</application>
</manifest> -
FlutterSecureStorage から sharedprefs を除外します。
アプリの android:fullBackupContent を有効にする必要がある場合は、プラグインで使用される prefs を 除外 するバックアップルールを設定します:
<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>詳細については、flutter_secure_storage を確認してください。
flutter_web_auth
flutter_web_auth は Logto の flutter SDK の背後で使用されます。Logto の認可 (Authorization) ページを開くために、その webview ベースのインタラクションインターフェースに依存しています。
このプラグインは、iOS 12+ および macOS 10.15+ では ASWebAuthenticationSession、iOS 11 では SFAuthenticationSession、Android では Chrome Custom Tabs を使用し、Web では新しいウィンドウを開きます。 iOS 8+ でビルドできますが、現在サポートされているのは iOS 11 以上のみです。
Android でコールバック URL を登録する
Logto のサインインウェブページからコールバック URL をキャプチャするためには、サインイン redirectUri を 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>