【Flutter × Cognito】クライアントシークレットの利用で躓いたこと
使用するパケージ
amazon_cognito_identity_dart_2: ^3.2.0
サマリ
- CognitoUserPoolクラス以外に、CognitoUserクラスにもクライアントシークレットを設定できる
- resendConfirmationCode(),confirmRegistration()の処理を実行するときにCognitoUserオブジェクトにクライアントシークレットを設定する
- もしかしたら他の処理でもCognitoUserオブジェクトにクライアントシークレットを設定しないといけないかも
躓いた所
Cognitoを利用した認証フローを作成中、認証コードの再送処理を実装している際に
クライアントシークレットの設定で混乱した。
ErrorPattern
Pattern1:CognitoUserオブジェクトにクライアントシークレットを設定していない
CognitoUserPoolオブジェクト側にのみクライアントシークレットを設定していて、CognitoUserオブジェクトにはクライアントシークレットを設定していない状態だと、resendConfirmationCode()を実行したときに怒られます
詳細
エラーメッセージ:
CognitoClientException{statusCode: 400, code: NotAuthorizedException, name: NotAuthorizedException, message: Client XXXXXXXXXXXXXXXXXXXXXXXXXX is configured for secret but secret was not received}
意訳:
あんたのとこに登録されているXXXのクライアントにはシークレットが設定されてるのに受け取れなかったんだけど!!
final CognitoUser cognitoUser = CognitoUser(
email,
cognitoUserPoolWithSecret,
);
修正方法:
CognitoUserオブジェクト生成時にもクライアントシークレットを設定してあげる
final CognitoUser cognitoUser = CognitoUser(
email,
cognitoUserPoolWithoutSecret,
clientSecret: cognitoClientSecret,
);
final CognitoUser cognitoUser = CognitoUser(
email,
// CognitoUserPoolオブジェクトと重複してシークレットを設定してもOK
cognitoUserPoolWithSecret,
clientSecret: cognitoClientSecret,
);
Pattern2:公式のドキュメント通りに実装する(ええぇ)
公式のサンプルプログラムに掲載されている型宣言に不適切な箇所があり、脳死でコピペして使ってると型が違うよと怒られます。
詳細
エラーメッセージ:
type '_Map<String, dynamic>' is not a subtype of type 'String'
意訳:
型が違うよ(Map<String, dynamic>はStringに格納できないよ)
final String status;
try {
// statusに代入しようとすると'flutter: type '_Map<String, dynamic>' is not a subtype of type 'String''のエラーが出る
status = await cognitoUser.resendConfirmationCode();
} catch (e) {
if (context.mounted) {
print(e);
createSnackBar(context, 'エラーが発生しました。アプリを再起動してお試しください。 $e');
return;
}
}
修正方法:
statusの型宣言をdynamicにする
→resendConfirmationCode()の戻り値自体がdynamic
// ここ
final dynamic status;
try {
status = await cognitoUser.resendConfirmationCode();
} catch (e) {
print(e);
}
Discussion