【SwiftUI/Firebase】Realtime Databaseで再認証(reauthenticate)する方法!emailとGoogle

この記事からわかること

  • SwiftFirebaseRealtime Database再認証実行する方法
  • reauthenticateメソッド使い方クレデンシャル情報
  • emailアカウントGoogleアカウントの場合の再認証方法

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

Realtime Databaseで再認証する方法

Realtime Databaseではユーザー情報の編集やメールアドレスの変更、退会手続きを行うためにはユーザーが直近でログインしている必要があります。

ログインから時間を有している場合はユーザーに対して再認証を求めます。

reauthenticateメソッド

再認証の流れはユーザーのログイン方法(email/passwordやGoogleなど)によって異なりますが実行するのはFIRUserreauthenticateメソッドで共通しています。

user.reauthenticate(with: credential) { result, error in
    if error != nil {
        print("reauth:\(error.debugDescription)")
    } else {
        print("reauth: 再認証成功")
    }
}

引数にはユーザー情報を保持するクレデンシャル情報を渡します。

クレデンシャルとは?

クレデンシャルとはセキュリティ関連の用語の1つでユーザー認証に使用される情報の総称のことです。Authでもユーザーの認証情報をクレデンシャルと呼んでいます。

引数に渡すクレデンシャル情報はユーザーのログイン方法によって構築方法が異なります

email/passwordアカウントの再認証方法

まずは通常のemail/passwordアカウントで再認証するにはEmailAuthProviderを使ってクレデンシャルを構築します。

EmailAuthProvider.credential(withEmail: user.email ?? "", password: pass)

引数には再認証を行うユーザーのメールアドレスとパスワードを渡します。メールアドレスはcurrentUserのemailプロパティからも取得することができますがパスワードはユーザーから再度入力してもらう必要があります。

TextFieldで入力されたパスワードを使って再認証できるようなメソッドを実装してみました。再認証の結果はcompletionHandlerで受け取ることができます。

// MARK: - email再認証
func reauth(user:User,pass:String,completion: @escaping (Bool) -> Void ) {
        
  // let user = Auth.auth().currentUser //  引数ではなくこれでも可
  // emailアカウント再認証
  let credential = EmailAuthProvider.credential(withEmail: user.email ?? "", password: pass)
  user.reauthenticate(with: credential) { result, error in
      if error != nil {
          completion(false)
      } else {
          completion(true)
      }
  }
}

Googleアカウントでの再認証方法

Googleアカウントの場合はGoogleアカウントでログインする時の流れを利用してクレデンシャル情報を取得します。

GoogleではGoogleAuthProviderを使ってクレデンシャル情報を構築します。そのためにブラウザからGoogleアカウントを選択してもらう処理を挟んでおきます。

// MARK: - Google再認証
func reauthGoogle(user:User,completion: @escaping (Bool) -> Void ) {
    
    // Googleアカウント再認証
    guard let clientID = FirebaseApp.app()?.options.clientID else { return }
    let config = GIDConfiguration(clientID: clientID)
    
    let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene
    let rootViewController = windowScene?.windows.first!.rootViewController!
    
    GIDSignIn.sharedInstance.signIn(with: config, presenting: rootViewController!) { g_user, g_error in
        if let g_error = g_error {
            print("GIDSignInError: \(g_error.localizedDescription)")
            return
        }
        guard let authentication = g_user?.authentication,
              let idToken = authentication.idToken else { return }
        
        let credential = GoogleAuthProvider.credential(withIDToken: idToken, accessToken: authentication.accessToken)
        user.reauthenticate(with: credential) { result, error in
            if error != nil {
                completion(false)
            } else {
                completion(true)
            }
        }
    }
}

FacebookやTwitterなどの再認証

それ以外のクレデンシャルの構築方法は以下の通りです。

// Email/password  
let credential = EmailAuthProvider.credential(withEmail: email, password: password)
// Facebook
let credential = FacebookAuthProvider.credential(withAccessToken: FBSDKAccessToken.currentAccessToken().tokenString)
// Twitter
let credential = TwitterAuthProvider.credential(withToken: session.authToken, secret: session.authTokenSecret)
// Google
let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken, accessToken: authentication.accessToken)

実例:退会処理

例えばユーザーが退会(ユーザー情報を抹消)する時に再認証は必要になります。以下は退会処理に再認証を組み込んだ例です。

// MARK: - 退会処理
func withdrawal(pass:String,completion: @escaping (Bool) -> Void ) {
    
    if let user = Auth.auth().currentUser {
        reauth(user: user,pass: pass) { result in
            if result {
                // 再認証成功 → 退会処理
                user.delete { error in
                    if error != nil {
                        // エラー発生
                        print("withDrawal:\(error.debugDescription)")
                        completion(false)
                    } else {
                        // 退会成功
                        completion(true)
                    }
                }
            }else{
                // 再認証失敗
                completion(false)
            }
        }
    }
}

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index