FlutterでAmazon CognitoのHosted UIを利用してみた
こんにちは、CX事業本部IoT事業部の高橋雄大です。
CognitoでAzure AD(Azure Active Directory)を利用する際、組み込みUIではなくCognitoのHosted UI(ホストされたウェブUI)を使う必要があるため、FlutterでAmplifyのライブラリを使用してHosted UIを実装する方法について調べてみました。
Amplifyのライブラリを使用した組み込みUIの実装方法については次の記事で紹介しています。
本記事のゴール
Flutterで開発したiOSアプリからCognitoのHosted UIを利用します。
環境情報
項目 | 内容 |
---|---|
OS | macOS Monterey 12.3 (21E230) |
Visual Studio Code | 1.66.0 |
Xcode | 13.3 (13E113) |
Flutter | 2.10.4 |
Dart | 2.16.2 |
Cognitoのアプリ設定
Cognitoドメインを作成します。必要があればカスタムドメインを設定します。
許可されているコールバックURLと許可されているサインアウトURLにアプリケーションのURLを登録します。URLは他のアプリケーションと重複しないようにする必要があります。
iOSのプロパティ設定
iOSのプロパティ設定にアプリのURLを追加します。Xcodeで設定してもOKです。
<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>myapp</string> </array> </dict> </array>
ログイン機能を実装
Amplifyのパッケージをインストールします。
flutter pub add amplify_auth_cognito flutter pub add amplify_flutter
Amplifyの設定ファイルamplifyconfiguration.dart
を作成します。amplify-cli
を利用すれば自動で設定ファイルを生成することも可能ですが、Amplifyのセットアップが必要になるので、今回は手動でAmplifyの設定ファイルを作成します。
Amplifyの設定ファイルには、ユーザープールIDとアプリケーションクライアントIDを入力します。また、最初に作成ドメインと設定したコールバックURLも入力します。
const amplifyconfig = '''{ "auth": { "plugins": { "awsCognitoAuthPlugin": { "CognitoUserPool": { "Default": { "PoolId": "[COGNITO USER POOL ID]", "AppClientId": "[COGNITO USER POOL APP CLIENT ID]", "Region": "[REGION]" } }, "Auth": { "Default": { "OAuth": { "WebDomain": "[COGNITO WEB DOMAIN]", "AppClientId": "[COGNITO USER POOL APP CLIENT ID]", "SignInRedirectURI": "myapp://", "SignOutRedirectURI": "myapp://", "Scopes": [ "email", "openid", "profile" ] } } } } } } }''';
main.dart
でログイン機能を実装します。
import 'package:amplify_auth_cognito/amplify_auth_cognito.dart'; import 'package:amplify_flutter/amplify_flutter.dart'; import 'package:flutter/material.dart'; import 'amplifyconfiguration.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({Key? key}) : super(key: key); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { bool signedIn = false; Future<void> _configure() async { try { await Amplify.addPlugin(AmplifyAuthCognito()); await Amplify.configure(amplifyconfig); try { await Amplify.Auth.getCurrentUser(); setState(() { signedIn = true; }); } on AuthException { setState(() { signedIn = false; }); } print('Successfully configured'); } on Exception catch (e) { print('Error configuring Amplify: $e'); } } @override void initState() { super.initState(); _configure(); } Future<void> signIn() async { try { await Amplify.Auth.signInWithWebUI(); setState(() { signedIn = true; }); } on AuthException { setState(() { signedIn = false; }); } } Future<void> signOut() async { try { await Amplify.Auth.signOut(); setState(() { signedIn = false; }); } on AuthException { setState(() { signedIn = true; }); } } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('ホーム')), body: Center( child: Center( child: signedIn ? ElevatedButton( style: ElevatedButton.styleFrom( primary: Colors.red, ), child: const Text('ログアウト'), onPressed: () { signOut(); }) : ElevatedButton( child: const Text('ログイン'), onPressed: () { signIn(); })), ), ), ); } }
ログイン前はログインボタン、ログイン後はログアウトボタンが表示されます。
デバッグコンソールに次のようなエラーが出力される場合にはios/Podfile
でプラットフォームを設定する必要があります。AmplifyのパッケージはiOS11以上が要件になりますので、プラットフォームを指定する必要があります。エラー内容を見ると、プラットフォームが指定されていないので、iOS9が自動で選択されているようです。
o update [!] CocoaPods could not find compatible versions for pod "amplify_auth_cognito_ios":
Error output from CocoaPods: ↳ [!] Automatically assigning platform `iOS` with version `9.0` on target `Runner` because no platform was specified. Please specify a platform for this target in your Podfile. See `https://guides.cocoapods.org/syntax/podfile.html#platform`. Error running pod install Error launching application on iPhone 13 Pro Max. Exited (sigterm)
ios/Podfile
2行目のコメントアウトを解除してプラットフォームにiOS11を指定します。
# Uncomment this line to define a global platform for your project platform :ios, '11.0'
Podのキャッシュを更新します。
pod repo update
動作確認
CognitoのHosted UIでログインできることを確認します。
まとめ
CognitoのHosted UIは日本語に対応していないため、普段はあまり使うことがありませんが、Azure ADなどの外部IdPと連携する際には利用することになります。Hosted UIも組み込みUIと同様にAmplifyのライブラリで簡単に実装することができました。