【SwiftUI/Firebase】Realtime Databaseで再認証(reauthenticate)する方法!emailとGoogle
この記事からわかること
- SwiftでFirebaseのRealtime Databaseで再認証を実行する方法
- reauthenticateメソッドの使い方とクレデンシャル情報
- emailアカウントとGoogleアカウントの場合の再認証方法
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
Realtime Databaseで再認証する方法
Realtime Databaseではユーザー情報の編集やメールアドレスの変更、退会手続きを行うためにはユーザーが直近でログインしている必要があります。
ログインから時間を有している場合はユーザーに対して再認証を求めます。
reauthenticateメソッド
再認証の流れはユーザーのログイン方法(email/passwordやGoogleなど)によって異なりますが実行するのはFIRUser
のreauthenticate
メソッドで共通しています。
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)
}
}
}
}
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。