こんにちは、CX事業本部 Delivery部の若槻です。
今回は、FlutterアプリからAmazon Cognitoオーソライザーを設定したAPI Gateway REST APIを叩いてデータを取得する実装をしてみました。
実装
バックエンド側
バックエンド側は詳述はしませんが、次のような構成となります。
- Amazon API Gateway REST API
- Amazon Cognito Authorizer
- Lambda Function
実装方法は以前投稿した下記などが参考になりますので参照ください。
/users
パスをGETメソッドで叩くと、ユーザーデータのリストが取得できます。
[
{
"email":"user01@example.com",
"id":"d0357bd7-f545-4f94-83dc-47b47cbf53d5"
},
{
"email":"user02@example.com",
"id":"7032aecb-11ae-4e6d-bf48-7b67ef5dbbed"
}
]
モバイルアプリ側
モバイルアプリ側です。今回はProviderを使っていないのでmain.dart
で単一のWidgetで実装しています。
またAmplify SDKを使用したCognito認証の実装は高橋雄大さんの記事を大いに参考にさせて頂きました。
lib/main.dart
import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'amplifyconfiguration.dart';
const apiDomain = 'xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com'; //API Gatewayのドメインを指定
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;
String idToken = '';
List items = [];
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;
});
}
}
// IDトークン取得
Future<void> getIdToken() async {
try {
var response = await Amplify.Auth.fetchAuthSession(
options: CognitoSessionOptions(getAWSCredentials: true));
if (!response.isSignedIn) {
throw Exception('Auth session expired.');
}
var session = response as CognitoAuthSession;
setState(() {
idToken = session.userPoolTokens!.idToken;
});
} on Exception {
signedIn = false;
}
}
// IDトークンを使用してREST APIを叩きデータを取得
Future<void> getData() async {
if (idToken != '') {
http.Response response = await http.get(
Uri.https(
apiDomain,
'/v1/users',
),
headers: {'Authorization': idToken});
setState(() {
items = json.decode(response.body);
print(items);
});
}
}
@override
Widget build(BuildContext context) {
getIdToken();
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('ホーム')),
body: Center(
child: signedIn
? items.isEmpty
? ElevatedButton(
child: const Text('データ取得'),
onPressed: () {
getData();
})
: ListView.builder(
itemCount: items.length,
itemBuilder: (BuildContext context, int index) {
return Card(
child: Column(
children: <Widget>[
ListTile(
title: Text(items[index]['id']),
subtitle: Text(items[index]['email']),
),
],
),
);
},
)
: ElevatedButton(
child: const Text('ログイン'),
onPressed: () {
signIn();
})),
),
);
}
}
動作確認
サインイン前はログインボタンが表示されます。
ログインボタンをクリックしてCognitoのHosted UIを表示し、サインインを行います
サインインできました。サインイン後にはデータ取得ボタンが表示されます。
取得ボタンをクリックするとデータが取得され、ListViewに表示することができました。
おわりに
FlutterアプリからAmazon Cognitoオーソライザーを設定したAPI Gateway REST APIを叩いてデータを取得する実装をしてみました。
FlutterアプリのAPIバックエンドにAWSを採用する場合はよくある構成だと思います。
参考
以上