Firebase Auth에서 제공하는 전화번호 인증해보기
우선 Firebase Auth 전화번호 인증은, Slient Push Notification을 이용해 토큰을 보내기 때문에 Push Notification을 사용하는 것과 동일하다.
따라서 아래의 준비가 필요하다.
인증토큰은 Firebase project에 등록해야할 토큰으로 아래 과정을 통해서 만들 수 있다.
Developer Apple의 Member Center로 이동 후, Keys탭으로 간다.
적당히 알아볼 만한 이름을 작성하고, APNs를 체크 한 후 Continue - Register
그다음 Download가 나오는데
경고문을 찬찬히 읽어보면, 보안을 위해 다운로드 후에는 서버에서 해당 키를 삭제한다고 한다. 그러니까 다운받은 그것이 유일본이기 때문에 잃어버리지 않도록 안전한 곳에 보관해야 한다.
키를 다운받아 보면 AuthKey_ABCDEFGH~ 이런식으로 되어있는데 언더바 뒤의 알파벳,숫자 조합이 바로 키 아이디가 된다.
이제 디바이스 토큰, 인증 토큰(키), 그리고 하나 더 필요한 것은 TeamID인데 이것은 화면 우측 상단 계정에 이름 아래에 있다.
위 토큰을 이제 Firebase에 넣어주면 된다.
해당 내용은 파이어베이스 전화번호 인증 문서 참고
파이어베이스에 프로젝트에 앱을 등록했으면, 이제 프로젝트에 작성할 일만 남았다.
우선 본인은 SwiftUI로 했는데 SwiftUI 처음 진입하면 AppDelegate가 없다.
다음과 같이 작성해준다. (프로젝트명App.swift)
import SwiftUI
import Firebase
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()
return true
}
func application(_ application: UIApplication,
didReceiveRemoteNotification notification: [AnyHashable : Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
}
}
@main
struct FirebasePhoneAuthPracticeApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
노티피케이션의 기본적인 플로우는 아래와 같다.
application(_:didFinishLaunchingWithOptions:)
에서 registerForRemoteNotifications
를 통해 APN으로 디바이스 토큰을 전송한다application(_:didRegisterForRemoteNotificationsWithDeviceToken:)
호출하거나 토큰 등록에 실패했을 시 application(_:didFailToRegisterForRemoteNotificationsWithError:)
를 호출하여 알린다.그런데 Firebase 전화번호 Auth는 Slient Push Notification이기 때문에 application(_:didFinishLaunchingWithOptions:)
는 FirebaseApp초기화 때문에 필요하고 나머지는 필요하지 않다.
따라서 Slient Push를 이용하기 위한 사전 작업이 따로 필요하다.
Slient Push Notification은 사용자에게 보이지 않는 기능이고 백그라운드에서 동작한다. 따라서 Sining & Capabilites에 Background Modes를 추가하고 거기서 Remote Notifications을 체크 한다.
func application(
_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler:
@escaping (UIBackgroundFetchResult) -> Void
) {
...
}
application(_:didReceiveRemoteNotification:fetchCompletionHandler)
델리게이트 메서드가 있어야 한다. 해당 코드는 이미 작성했으므로 Slient Push Notification을 사용할 준비가 되었다.
또 Slient Push Notification은 유저에게 알람이 발생하지 않으므로 알람에 대한 동의를 받을 필요가 없다.
인증하는 작업 플로우는 다음과 같다.
func requestVerifyCode() {
buttonDisabled = true
let validPhoneNumber = "+82\(phoneNumber)"
PhoneAuthProvider.provider().verifyPhoneNumber(validPhoneNumber, uiDelegate: nil) { verification, error in
if let error = error {
print("error: \(error)")
buttonDisabled = false
} else {
self.verificationId = verification
withAnimation {
watingVeryfiId = true
}
}
}
}
텍스트필드에 입력된 전화번호를 검증하고 Firebase서버에 요청하는 코드로
verifyPhoneNumber(_:uiDelegate:completion:) 메서드를 통해 요청한다.
첫번째 인자에 유저가 입력한 전화번호가 들어가면 된다. 입력은 통상적으로 입력하는 010~ 패턴이면 되는데 앞에 국가코드를 포함해야 한다.
전화번호 검증이 성공했을 때 인증코드가 전화번호로 날아오게 된다.
func verifyLogin() {
isVerifying = true
let credential = PhoneAuthProvider.provider().credential(withVerificationID: verificationId ?? "", verificationCode: userVerify)
Auth.auth().signIn(with: credential) { (success, error) in
if let error = error {
print("error: \(error.localizedDescription)")
} else {
print("success")
showMainView = true
}
isVerifying = false
}
}
이제 유저가 받은 인증코드를 다른 텍스트필드에 입력하고, 1에서 받은 인증코드와 비교하는 메서드를 작성한다.
credential(withVerificationID:verificationCode)
메소드에 첫번째 인자는 verifyPhoneNumber메서드로 받은 인증코드, 그리고 두번째 인자에는 유저가 입력한 인증코드가 된다. 두 개가 일치하게 되면 인증이 성공하는 것이다.
기본 코드만 작성 한 것으로 토큰 관리나, 로그인 상태 관리 등은 꼭 별도로 해야한다!