👻

【Flutter × Go】退会処理:Firebase Auth削除時の「requires-recent-login」エラー対処法

2024/05/07に公開

はじめに

おしゃべり猫型ロボット「ミーア」で、アプリでユーザーの退会動線を作成したが、退会するボタンを押した時に下記エラーが生じた。

[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を追加する。

https://github.com/firebase/firebase-admin-go

# 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を使用して、認証情報のオプションを設定。

そして、設定した、、、

続きはこちらで記載しています。
https://kazulog.fun/dev/firebase-auth-delete-requires-recent-login/

Discussion