[iOS] - FireBase를 통한 SMS전화번호 인증하기
Firebase로 전화번호 인증
- Firebase를 사용하기 위해서 첫번째로 Apple프로젝트에 Firebase를 추가해야합니다.
- https://firebase.google.com/docs/ios/setup?hl=ko - 공식문서에 자세한 방법이 설명되어 있습니다.
- https://console.firebase.google.com/ - console링크
- https://console.firebase.google.com/ - console링크
🚨 GoogleService-Info.plist를 추가하기 전에 원격저장소(Github)에 프로젝트를 업로드한다면 제거하고 올리는 것을 권장 (개인정보 유출 가능성이 있습니다.)
iOS에서 전화번호로 Firebase에 인증
- https://firebase.google.com/docs/auth/ios/phone-auth?hl=ko - 공식문서
- Firebase 인증을 사용하면 사용자의 전화로 SMS 메시지를 전송하여 로그인하는 것이 가능합니다. 사용자는 SMS 메시지에 포함된 일회용 코드를 사용하여 로그인합니다.
- 여러 Firebase제품 중 인증에 관련된 Auth를 추가합니다.
- https://firebase.google.com/docs/ios/swift-package-manager?hl=ko - SPM설치
pod 'Firebase/Auth'
- CocoaPods
Firebase 프로젝트에서 전화번호 로그인 사용 설정
- Console에서 Authetication섹션에서 Sign in method탭에서 전화를 제공합니다.
앱 인증 사용 설정
전화번호 인증을 사용하려면 Firebase에서 전화번호 로그인 요청이 내 앱에서 발생한 것인지 확인할 수 있어야 합니다.
Silent APN 알림
: 기기에서 처음으로 전화번호를 통해 사용자를 로그인 처리하면 Firebase 인증에서 사용자 모르게 기기로 푸시 알림을 전송하여 토큰을 보냅니다.- iOS 8.0이상은 silent notification은 사용자의 권한요청이 필수가 아닙니다.
reCAPTCHA 인증
: 사용자가 앱의 백그라운드 새로고침을 중지했거나 iOS 시뮬레이터에서 앱을 테스트하는 경우와 같이 자동 푸시 알림을 주고받을 수 없는 경우, Firebase 인증은 reCAPTCHA 인증을 사용하여 전화번호 로그인 과정을 완료합니다.
사용자 전화로 인증 코드 보내기
사용자에게 전화번호를 제공하도록 요청하는 UI를 작성한 후, verifyPhoneNumber:UIDelegate:completion:
를 호출하여 Firebase가 사용자의 전화에 SMS로 인증 코드를 전송하도록 요청합니다.
var phoneNumber = "123-456-789" // 전화번호
PhoneAuthProvider.provider()
.verifyPhoneNumber(phoneNumber, uiDelegate: nil) { verificationID, error in
if let error = error {
self.showMessagePrompt(error.localizedDescription)
return
}
// 에러가 없다면 사용자에게 인증코드와 verificationID(인증ID) 전달
}
verifyPhoneNumber:UIDelegate:completion:
가 호출하면 Firebase가 앱에 사용자 모르게 푸시 알림을 보내거나 사용자에게 reCAPTCHA 챌린지를 표시합니다.- 지정된 전화번호로 인증코드가 포함된 SMS메시지를 보낸 후 성공적으로 처리되면 인증ID를 전달합니다.
- 전달된 인증 ID는 UserDefault 및 DB에 저장합니다.
- Auth 인스턴스의
languageCode
속성을 사용하여 인증언어를 지정하면 SMS메시지를 현지화할 수 있습니다.Auth.auth().languageCode = "kr"
권장사항
- 지역마다 법에따라 다르지만, 일반적으로 사용자에게 SMS메시지가 발송되고 요금이 발생할 수 있다는 점을 알려야 합니다.
인증코드로 사용자 로그인 처리
정상적으로 인증코드와 인증ID를 받았다면 signInWithCredential:completion:
를 호출하여 FIRPhoneAuthCredential
객체를 만든 후 사용자로그인합니다.
FIRPhoneAuthCredential
객체 생성let credential = PhoneAuthProvider.provider().credential( withVerificationID: verificationID, verificationCode: verificationCode )
FIRPhoneAuthCredential
객체를 사용하여 로그인Auth.auth().signIn(with: credential) { authResult, error in if let error = error { print(error.debugDescription) } // 인증 완료 -> 로그인 진행 }
- 세부적인 에러처리는 공식문서 참고
가상 전화번호로 할당량제한 없이 테스트하기
가상전화번호로 테스트 장점
- 할당량을 소모하지 않고 전화번호 인증을 테스트합니다.
- 실제 SMS 메시지를 보내지 않고 전화번호 인증을 테스트합니다.
- 동일한 전화번호로 연속으로 테스트를 하는경우 위험없이 실행할 수 있습니다. (앱스토어 리뷰과정에서 리뷰어가 같은 전화번호로 테스트를 할 때 reject의 위험을 최소화할 수 있습니다.)
- 시뮬레이터에서 테스트를 쉽게 할 수 있습니다.
- 실제 전화번호에 적용되는 보안검사를 하지않고 테스트를 할 수 있습니다.
가상전화번호를 위한 요구사항
- 실제로 존재하지 않는 전화번호를 사용해야합니다.
- 가상전화번호는 최대 10개까지 추가할 수 있습니다.
- 추측하기 어려운 테스트 전화번호/코드를 사용하고 자주 변경합니다.
- 전화번호는 길이 및 기타 제약 조건에 따라 올바른 형식이어야 합니다.(실제번호처럼 동일한 유효성검사를 진행합니다.)
가상전화번호 생성하기
-
Console에서 Authetication섹션에서 Sign in method탭에서 전화번호를 제공합니다.
-
로그인이 완료되면 해당전화번호로 Firebase사용자가 생성됩니다.
-
사용자는 실제 전화번호 사용자와 동일한 행동 및 속성을 가지며 동일한 방식으로 실시간 데이터베이스/Cloud Firestore 및 기타 서비스에 액세스할 수 있습니다. 이 과정에서 생성된 ID 토큰은 실제 전화번호 사용자와 동일한 서명을 갖습니다.
-
Control Access with Custom Claims and Security Rules - Firebase Admin SDK는 사용자계정 커스텀을 지원합니다.
- 사용자에게 데이터나 리소스에 접근할 관리자권한을 줄 수 있습니다.
- 사용자가 속한 다른 그룹을 정의할 수 있습니다.
- 다양한 단계 접근을 제공합니다.
- 유료/무료 가입자
- 관리자 및 일반사용자
- 교사 및 학생
통합 테스트
Firebase Authentication
는 수동으로 테스트를 진행하는 경우, reCAPTCHA인증 및 silent push notifications를 무시하고 진행할 수 있습니다.-
appVerificationDisabledForTesting
값을 TRUE로 설정 -
가상전화번호만 사용할 수 있습니다.
let phoneNumber = "+15605551342" let testVerificationCode = "220118" Auth.auth().settings?.isAppVerificationDisabledForTesting = true PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate:nil) { (verificationID, error) in if error != nil { print("인증Error: \(error.debugDescription)") return } let credential = PhoneAuthProvider.provider().credential(withVerificationID: verificationID ?? "", verificationCode: testVerificationCode) Auth.auth().signIn(with: credential) { (authData, error) in if error != nil { print("로그인Error: \(error.debugDescription)") return } print("authData: \(authData)") } }
-
🚨 Capability에서 Background Modes에 Remote notifications가 체크되어 있으면 에러가 발생함
-
Swizzling 없이 전화번호 로그인
Swizzling이란? 런타임때 어떤 메서드를 다른 메서드로 바꾸는 것을 말합니다.
Firebase가 silent push notification으로 APNs 토큰을 얻거나, reCAPTCHA 지정한 custom scheme으로 리다이렉트를 하는 과정에서 Swizzling을 합니다.
- swizzling 사용하지 않는다면 명시적으로 APNs 토큰을 전달하고 redirect URL도 제공해야합니다.
Swizzling 비활성화
- info.plist에서
FirebaseAppDelegateProxyEnabled
속성울 추가한 후 No로 설정합니다. (Firebase 모든 products에서 swizzling 비활성화) ****
-
APNs device token 얻기
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { // 디바이스토큰을 auth에 전달 Auth.auth().setAPNSToken(deviceToken, type: .prod) // 앱에서 필요한 경우 디바이스토큰 추가 처리 // ... }
-
redirect URL
// AppDelegate.swift // iOS 9이상 func application(_ application: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any]) -> Bool { if Auth.auth().canHandle(url) { return true } } // iOS 9미만 func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool { if Auth.auth().canHandle(url) { return true } } // SceneDelegate.swift func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) { for urlContext in URLContexts { let url = urlContext.url Auth.auth().canHandle(url) } }
사용자가 로그인 되면 Firebase프로젝트에 정보가 저장
- 사용자가 처음 로그인하면 새로운 사용자 계정이 생성되고 사용자 이름 및 암호, 전화 번호 또는 인증 공급자 정보와 같은 자격 증명에 연결됩니다.
- 새로운 계정은 Firebase 프로젝트의 일부로 저장되며, 사용자가 로그인하는 방법에 관계없이 프로젝트의 모든 앱에서 사용자를 식별하는 데 사용할 수 있습니다.
- 따라서 FIRUser객체에서 사용자의 기본 프로필 정보를 가져올 수 있습니다.
- Manage Users in Firebase
- Firebase 실시간 데이터베이스 및 클라우드 저장소 보안 규칙에서는
auth
변수에서 로그인한 사용자의 고유 사용자 ID를 가져와 사용자가 액세스할 수 있는 데이터를 제어할 수 있습니다. - Link Multiple Auth Providers to an Account on Apple Platforms
- 인증 세부적인 에러처리 - Handle Firebase Apple Platforms Auth Errors
로그아웃
let firebaseAuth = Auth.auth()
do {
try firebaseAuth.signOut()
} catch let signOutError as NSError {
print("Error signing out: %@", signOutError)
}
💡 Authentication vs
Authorization vs
Certification
- Authentication
- (사용 또는 입장하는 상황에서) 인증
- ex. 로그인하는 절차
- Authorization
- (권한) 인증
- ex. 로그인 한 계정이 관리자인지, 일반사용자인지 구분하는 절차
- Certification
- (심사를 통과한) 인증
- 일정 기준을 넘었을때 주어지는 것
참고링크
- Firebase 블로그
- 문자 인증번호 자동완성 - https://im-designloper.tistory.com/59
- Swizzling 블로그
- URL Scheme 등록 - https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app
- Apple push notification service (APNs) 설정하기 - https://spiralmoon.tistory.com/entry/Apple-Apple-push-notification-service-APNs-설정하기
- authentication 과 authorization의 차이 - https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=iq_up&logNo=100057746027
Author And Source
이 문제에 관하여([iOS] - FireBase를 통한 SMS전화번호 인증하기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@sookim-1/iOS-FireBase를-통한-SMS전화번호-인증하기
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Author And Source
이 문제에 관하여([iOS] - FireBase를 통한 SMS전화번호 인증하기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@sookim-1/iOS-FireBase를-통한-SMS전화번호-인증하기저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)