こんにちは、CX事業本部 Delivery部の若槻です。
以前のエントリで、Flutter(iOS)アプリでAmplify SDKを使ってAmazon Cognitoの認証をする実装をしました。
この時にAmplifyのセッションを使って自身の属性情報を取得しようとした際にハマったので対処について共有します。
事象
Flutter Amplifyを使って自身の属性情報を取得したい場合は、ドキュメントを見るとfetchCurrentUserAttributes()
を使えば良さそう。
Future<void> fetchCurrentUserAttributes() async {
try {
final result = await Amplify.Auth.fetchUserAttributes();
for (final element in result) {
print('key: ${element.userAttributeKey}; value: ${element.value}');
}
} on AuthException catch (e) {
print(e.message);
}
}
試してみます。環境は以前のエントリで作成したアプリを流用しています。
import 'package:flutter/material.dart';
import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:amplify_flutter/amplify_flutter.dart';
import 'amplifyconfiguration.dart';
class AuthProvider extends ChangeNotifier {
bool signedIn = false;
Future<void> _configure() async {
if (!Amplify.isConfigured) {
await Amplify.addPlugin(AmplifyAuthCognito());
await Amplify.configure(amplifyconfig);
}
try {
var currentUser = await Amplify.Auth.getCurrentUser();
print(currentUser.userId);
print(currentUser.username);
var userAttributes = await Amplify.Auth.fetchUserAttributes();
for (final element in userAttributes) {
print('key: ${element.userAttributeKey}; value: ${element.value}');
}
signedIn = true;
} on AuthException catch (e) {
print(e);
signedIn = false;
}
notifyListeners();
}
}
しかし実行すると例外がスローされてしまいます。getCurrentUser()
までは実行できていますが、fetchUserAttributes()
でエラーが発生してしまいます。
flutter: 5ed9abb6-f549-4d8c-9288-c39012b8f4bd
flutter: 5ed9abb6-f549-4d8c-9288-c39012b8f4bd
[VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: NotAuthorizedException(message: Access Token does not have required scopes, recoverySuggestion: Check whether the given values are correct and the user is authorized to perform the operation., underlyingException: null)
#0 AmplifyAuthCognitoMethodChannel.fetchUserAttributes (package:amplify_auth_cognito/method_channel_auth_cognito.dart:297:7)
<asynchronous suspension>
#1 AuthProvider._configure (package:flutter_sample_app/auth_provider.dart:20:26)
<asynchronous suspension>
原因、解決
アクセストークンのスコープにaws.cognito.signin.user.admin
が含まれていないことが原因でした。
Amazon Cognitoの一部のAPIはaws.cognito.signin.user.admin
スコープを付与する必要があるようです。
aws.cognito.signin.user.admin スコープは、UpdateUserAttributes および VerifyUserAttribute などのアクセストークンを必要とする Amazon Cognito ユーザープール API 操作へのアクセス権を付与します。
Amplify.configure()
で読み込みコンフィグファイルのスコープにaws.cognito.signin.user.admin
を追加します。
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",
"aws.cognito.signin.user.admin"
]
}
}
}
}
}
}
}''';
また今回は認証画面にHosted UIを使っていたため、User pool clientのHosted UIの設定でもaws.cognito.signin.user.admin
を追加します。(Hosted UIの設定で追加せず、コンフィグファイル側にのみ追加した場合はサインインすらできない状態となります。)
スコープ修正後に再度実行すると、email
およびemail_verified
などの属性情報が取得できました。
Performing hot restart...
Restarted application in 287ms.
flutter: 5ed9abb6-f549-4d8c-9288-c39012b8f4bd
flutter: 5ed9abb6-f549-4d8c-9288-c39012b8f4bd
flutter: key: sub; value: 5ed9abb6-f549-4d8c-9288-c39012b8f4bd
flutter: key: email; value: hoge@example.com
flutter: key: email_verified; value: true
おわりに
Flutter Amplifyでアプリ(iOS)から自身の属性情報を取得しようとするとエラーとなる際の確認ポイントについてでした。
なんで自分の情報を取得できないのか最初は混乱しましたが、fetchCurrentUserAttributes()
も管理権限が必要なAPIの一種であるという観点が抜けていました。
参考
以上