【Flutter × Go】退会処理:Firebase Auth削除時の「requires-recent-login」エラー対処法
はじめに
おしゃべり猫型ロボット「ミーア」で、アプリでユーザーの退会動線を作成したが、退会するボタンを押した時に下記エラーが生じた。
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: [firebase_auth/requires-recent-login] This operation is sensitive and requires recent authentication. Log in again before retrying this request.
#0 FirebaseAuthUserHostApi.delete (package:firebase_auth_platform_interface/src/pigeon/messages.pigeon.dart:1581:7)
<asynchronous suspension>
#1 MethodChannelUser.delete (package:firebase_auth_platform_interface/src/method_channel/method_channel_user.dart:35:7)
<asynchronous suspension>
#2 UserNotifier.deleteUser (package:clocky_app/api/user_notifier.dart:31:7)
<asynchronous suspension>
Firebase Authを使ったユーザー退会処理時の「requires-recent-login」エラーの対処法について記載。
何が問題なのか?最近のログインがない場合に発生
現状のFlutterの、ユーザー退会処理のコードがこちら。
// lib/api/user_notifier.dart
class UserNotifier extends StateNotifier<User?> {
final ApiClient apiClient;
UserNotifier(this.apiClient) : super(null);
Future<void> deleteUser() async {
// DBのデータを削除
await apiClient.deleteUser(state?.uid ?? '');
// Firebase Authデータを削除
auth.User? currentUser = auth.FirebaseAuth.instance.currentUser;
if (currentUser != null) {
await currentUser.delete();
}
state = null;
}
}
FirebaseAuthクラスのdeleteメソッドの定義を確認すると、下記のwarningが記載されていた。
/// Deletes and signs out the user.
///
/// **Important**: this is a security-sensitive operation that requires the
/// user to have recently signed in. If this requirement isn't met, ask the
/// user to authenticate again and then call [User.reauthenticateWithCredential].
///
/// A [FirebaseAuthException] maybe thrown with the following error code:
/// - **requires-recent-login**:
/// - Thrown if the user's last sign-in time does not meet the security
/// threshold. Use [User.reauthenticateWithCredential] to resolve. This
/// does not apply if the user is anonymous.
Future<void> delete() async {
return _delegate.delete();
}
このエラーは、セキュリティ上の理由で、ユーザーが最近ログインしていない場合に発生する。ユーザーを退会させる前に、再認証(reauthentication)させる必要がある。
ちなみに、何日ログインしていないとこのエラーが表示されるかは、Firebaseのドキュメントには自分が見た限りでは明記されていなかった。
また、今回の問題とは直接的な関係はないが、DBのユーザーデータ削除をFirebase Authデータ削除に先んじて行っていたため、「退会する」ボタンを押すと、DBからユーザーデータは削除されたにも関わらず、Firebase Authデータは削除されずに残ったままという現象が発生していたので、こちらも回収する必要がある。
Firebase Authの退会処理を、Flutterのフロントエンドではなく、Goのサーバー側でFirebase Admin SDKを使用して、実行する仕様に変更する。 SDKは自動的にトークンの有効期限を管理し、必要に応じてトークンを更新するので、開発者はトークンの有効期限切れこれにより、クライアント側での認証状態の管理とは切り離され、再認証エラー問題は発生しなくなる。
Go:Firebase Authの退会処理を実装
サーバーにFirebase Admin SDKを追加
Firebase Admin SDK は、特権環境から Firebase を操作するために使用するサーバー ライブラリのセット。下記を実行してSDKを追加する。
# Install the latest version:
go install firebase.google.com/go/v4@latest
# Or install a specific version:
go install firebase.google.com/go/v4@4.13.0
OAuth 2.0 更新トークンを使用してSDKを初期化
Firebase Go SDKをインポートし、 Config構造体に格納されているGoogleApplicationCredentialsを使用して、認証情報のオプションを設定。
そして、設定した、、、
続きはこちらで記載しています。
Discussion