اگر به Firebase Authentication with Identity Platform ارتقا داده اید، می توانید احراز هویت چند مرحله ای SMS را به برنامه iOS خود اضافه کنید.
احراز هویت چند عاملی امنیت اپلیکیشن شما را افزایش می دهد. در حالی که مهاجمان اغلب رمزهای عبور و حساب های اجتماعی را به خطر می اندازند، رهگیری یک پیام متنی دشوارتر است.
قبل از شروع
حداقل یک ارائه دهنده را فعال کنید که از احراز هویت چند عاملی پشتیبانی می کند. هر ارائهدهندهای از MFA پشتیبانی میکند، بهجز احراز هویت تلفن، احراز هویت ناشناس و Apple Game Center.
مطمئن شوید که برنامه شما ایمیل های کاربر را تأیید می کند. وزارت امور خارجه به تأیید ایمیل نیاز دارد. این امر مانع از ثبت نام عوامل مخرب در سرویسی با ایمیلی می شود که متعلق به آنها نیست و سپس با افزودن عامل دوم، مالک واقعی را قفل می کند.
فعال کردن احراز هویت چند عاملی
صفحه Authentication > Sign-in را در کنسول Firebase باز کنید.
در بخش Advanced ، SMS Multi-factor Authentication را فعال کنید.
همچنین باید شماره تلفن هایی را که برنامه خود را با آنها آزمایش می کنید وارد کنید. در حالی که اختیاری است، ثبت شماره تلفن های آزمایشی قویاً توصیه می شود تا در حین توسعه ایجاد فشار نشود.
اگر قبلاً دامنه برنامه خود را تأیید نکردهاید، آن را به فهرست مجاز در صفحه تأیید هویت > تنظیمات کنسول Firebase اضافه کنید.
در حال تأیید برنامه شما
Firebase باید تأیید کند که درخواستهای پیامکی از برنامه شما میآیند. شما می توانید این کار را به دو صورت انجام دهید:
اعلانهای APN بیصدا : وقتی برای اولین بار به یک کاربر وارد میشوید، Firebase میتواند یک اعلان فشار بیصدا به دستگاه کاربر ارسال کند. اگر برنامه اعلان را دریافت کند، احراز هویت میتواند ادامه یابد. توجه داشته باشید که با شروع iOS 8.0، نیازی نیست که از کاربر بخواهید اجازه دهد تا اعلانهای فشاری از این روش استفاده کنند.
راستیآزمایی reCAPTCHA : اگر نمیتوانید یک اعلان بیصدا ارسال کنید (مثلاً به این دلیل که کاربر بهروزرسانی پسزمینه را غیرفعال کرده است، یا برنامه خود را در شبیهساز iOS آزمایش میکنید)، میتوانید از reCAPTCHA استفاده کنید. در بسیاری از موارد، reCAPTCHA به طور خودکار و بدون تعامل کاربر حل می شود.
استفاده از اعلان های بی صدا
برای فعال کردن اعلانهای APN برای استفاده با Firebase :
در Xcode، اعلانهای فشاری را برای پروژه خود فعال کنید .
کلید احراز هویت APN خود را با استفاده از کنسول Firebase آپلود کنید (تغییرات شما به طور خودکار به Google Cloud Firebase منتقل می شود). اگر از قبل کلید احراز هویت APN خود را ندارید، به پیکربندی APN با FCM مراجعه کنید تا نحوه دریافت آن را بیاموزید.
کنسول Firebase را باز کنید.
به تنظیمات پروژه بروید.
تب Cloud Messaging را انتخاب کنید.
در بخش APNs Authentication key ، در بخش پیکربندی برنامه iOS ، روی آپلود کلیک کنید.
کلید خود را انتخاب کنید
شناسه کلید را برای کلید اضافه کنید. میتوانید شناسه کلید را در قسمت گواهیها، شناسهها و نمایهها در مرکز اعضای برنامهنویس اپل بیابید.
روی آپلود کلیک کنید.
اگر قبلاً یک گواهی APN دارید، میتوانید گواهی را به جای آن آپلود کنید.
با استفاده از تأیید reCAPTCHA
برای فعال کردن SDK مشتری برای استفاده از reCAPTCHA:
پیکربندی پروژه خود را در Xcode باز کنید.
روی نام پروژه در نمای درختی سمت چپ دوبار کلیک کنید.
برنامه خود را از قسمت Targets انتخاب کنید.
تب اطلاعات را انتخاب کنید.
بخش انواع URL را باز کنید.
روی دکمه + کلیک کنید.
شناسه مشتری معکوس خود را در قسمت طرحهای URL وارد کنید. میتوانید این مقدار را در فایل پیکربندی
GoogleService-Info.plist
بهعنوانREVERSED_CLIENT_ID
پیدا کنید.
پس از تکمیل، پیکربندی شما باید شبیه به شکل زیر باشد:
در صورت تمایل، میتوانید روشی را که برنامهتان SFSafariViewController
یا UIWebView
هنگام نمایش reCAPTCHA ارائه میکند، سفارشی کنید. برای انجام این کار، یک کلاس سفارشی ایجاد کنید که با پروتکل FIRAuthUIDelegate
مطابقت دارد و آن را به verifyPhoneNumber:UIDelegate:completion:
ارسال کنید.
انتخاب الگوی ثبت نام
میتوانید انتخاب کنید که آیا برنامه شما به احراز هویت چند مرحلهای نیاز دارد یا خیر، و چگونه و چه زمانی کاربران خود را ثبتنام کند. برخی از الگوهای رایج عبارتند از:
فاکتور دوم کاربر را به عنوان بخشی از ثبت نام ثبت کنید. اگر برنامه شما نیاز به احراز هویت چند عاملی برای همه کاربران دارد، از این روش استفاده کنید. توجه داشته باشید که یک حساب کاربری باید یک آدرس ایمیل تأیید شده برای ثبت عامل دوم داشته باشد، بنابراین جریان ثبت نام شما باید این مورد را رعایت کند.
برای ثبت فاکتور دوم در حین ثبت نام، یک گزینه قابل پرش ارائه دهید. برنامههایی که میخواهند احراز هویت چندعاملی را تشویق کنند، اما نیازی به احراز هویت ندارند، ممکن است این رویکرد را ترجیح دهند.
به جای صفحه ثبت نام، امکان اضافه کردن فاکتور دوم را از صفحه مدیریت حساب کاربری یا نمایه کاربر فراهم کنید. این امر اصطکاک را در طول فرآیند ثبت نام به حداقل می رساند، در حالی که هنوز احراز هویت چند عاملی را برای کاربران حساس به امنیت در دسترس قرار می دهد.
هنگامی که کاربر میخواهد به ویژگیهایی با الزامات امنیتی افزایش یافته دسترسی پیدا کند، باید فاکتور دوم را به صورت تدریجی اضافه کنید.
ثبت عامل دوم
برای ثبت یک عامل ثانویه جدید برای یک کاربر:
احراز هویت مجدد کاربر
از کاربر بخواهید شماره تلفن خود را وارد کند.
یک جلسه چند عاملی برای کاربر دریافت کنید:
سویفت
authResult.user.multiFactor.getSessionWithCompletion() { (session, error) in // ... }
هدف-C
[authResult.user.multiFactor getSessionWithCompletion:^(FIRMultiFactorSession * _Nullable session, NSError * _Nullable error) { // ... }];
یک پیام تأیید به تلفن کاربر ارسال کنید. مطمئن شوید که شماره تلفن با علامت
+
و بدون علامت یا فضای خالی دیگر قالب بندی شده است (به عنوان مثال:+15105551234
)سویفت
// Send SMS verification code. PhoneAuthProvider.provider().verifyPhoneNumber( phoneNumber, uiDelegate: nil, multiFactorSession: session) { (verificationId, error) in // verificationId will be needed for enrollment completion. }
هدف-C
// Send SMS verification code. [FIRPhoneAuthProvider.provider verifyPhoneNumber:phoneNumber UIDelegate:nil multiFactorSession:session completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) { // verificationId will be needed for enrollment completion. }];
اگرچه لازم نیست، بهترین روش این است که از قبل به کاربران اطلاع دهید که پیامک دریافت خواهند کرد و نرخ های استاندارد اعمال می شود.
متد
verifyPhoneNumber()
فرآیند تأیید برنامه را در پسزمینه با استفاده از اعلان فشار بیصدا آغاز میکند. اگر اعلان فشار بیصدا در دسترس نباشد، به جای آن یک چالش reCAPTCHA صادر میشود.پس از ارسال کد پیامک، از کاربر بخواهید که کد را تأیید کند. سپس، از پاسخ آنها برای ساخت
PhoneAuthCredential
استفاده کنید:سویفت
// Ask user for the verification code. Then: let credential = PhoneAuthProvider.provider().credential( withVerificationID: verificationId, verificationCode: verificationCode)
هدف-C
// Ask user for the SMS verification code. Then: FIRPhoneAuthCredential *credential = [FIRPhoneAuthProvider.provider credentialWithVerificationID:verificationID verificationCode:kPhoneSecondFactorVerificationCode];
مقداردهی اولیه یک شیء ادعا:
سویفت
let assertion = PhoneMultiFactorGenerator.assertion(with: credential)
هدف-C
FIRMultiFactorAssertion *assertion = [FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
تکمیل ثبت نام به صورت اختیاری، می توانید یک نام نمایشی برای فاکتور دوم تعیین کنید. این برای کاربرانی که چندین عامل دوم دارند مفید است، زیرا شماره تلفن در جریان احراز هویت پنهان میشود (به عنوان مثال 1234*******+1).
سویفت
// Complete enrollment. This will update the underlying tokens // and trigger ID token change listener. user.multiFactor.enroll(with: assertion, displayName: displayName) { (error) in // ... }
هدف-C
// Complete enrollment. This will update the underlying tokens // and trigger ID token change listener. [authResult.user.multiFactor enrollWithAssertion:assertion displayName:nil completion:^(NSError * _Nullable error) { // ... }];
کد زیر یک مثال کامل از ثبت فاکتور دوم را نشان می دهد:
سویفت
let user = Auth.auth().currentUser
user?.multiFactor.getSessionWithCompletion({ (session, error) in
// Send SMS verification code.
PhoneAuthProvider.provider().verifyPhoneNumber(
phoneNumber,
uiDelegate: nil,
multiFactorSession: session
) { (verificationId, error) in
// verificationId will be needed for enrollment completion.
// Ask user for the verification code.
let credential = PhoneAuthProvider.provider().credential(
withVerificationID: verificationId!,
verificationCode: phoneSecondFactorVerificationCode)
let assertion = PhoneMultiFactorGenerator.assertion(with: credential)
// Complete enrollment. This will update the underlying tokens
// and trigger ID token change listener.
user?.multiFactor.enroll(with: assertion, displayName: displayName) { (error) in
// ...
}
}
})
هدف-C
FIRUser *user = FIRAuth.auth.currentUser;
[user.multiFactor getSessionWithCompletion:^(FIRMultiFactorSession * _Nullable session,
NSError * _Nullable error) {
// Send SMS verification code.
[FIRPhoneAuthProvider.provider
verifyPhoneNumber:phoneNumber
UIDelegate:nil
multiFactorSession:session
completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) {
// verificationId will be needed for enrollment completion.
// Ask user for the verification code.
// ...
// Then:
FIRPhoneAuthCredential *credential =
[FIRPhoneAuthProvider.provider credentialWithVerificationID:verificationID
verificationCode:kPhoneSecondFactorVerificationCode];
FIRMultiFactorAssertion *assertion =
[FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
// Complete enrollment. This will update the underlying tokens
// and trigger ID token change listener.
[user.multiFactor enrollWithAssertion:assertion
displayName:displayName
completion:^(NSError * _Nullable error) {
// ...
}];
}];
}];
تبریک می گویم! شما با موفقیت دومین فاکتور احراز هویت را برای یک کاربر ثبت کردید.
ورود کاربران با فاکتور دوم
برای ورود به یک کاربر با تأیید پیام کوتاه دو مرحله ای:
کاربر را با اولین فاکتور وارد کنید، سپس خطایی را که نشان میدهد احراز هویت چند عاملی لازم است، بیابید. این خطا حاوی یک حلکننده، نکاتی در مورد فاکتورهای دوم ثبتشده، و یک جلسه اساسی است که تأیید هویت کاربر با فاکتور اول را با موفقیت تأیید میکند.
برای مثال، اگر اولین عامل کاربر ایمیل و رمز عبور باشد:
سویفت
Auth.auth().signIn( withEmail: email, password: password ) { (result, error) in let authError = error as NSError if authError?.code == AuthErrorCode.secondFactorRequired.rawValue { // The user is a multi-factor user. Second factor challenge is required. let resolver = authError!.userInfo[AuthErrorUserInfoMultiFactorResolverKey] as! MultiFactorResolver // ... } else { // Handle other errors such as wrong password. } }
هدف-C
[FIRAuth.auth signInWithEmail:email password:password completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { if (error == nil || error.code != FIRAuthErrorCodeSecondFactorRequired) { // User is not enrolled with a second factor and is successfully signed in. // ... } else { // The user is a multi-factor user. Second factor challenge is required. } }];
اگر اولین عامل کاربر یک ارائه دهنده فدرال، مانند OAuth است، پس از فراخوانی
getCredentialWith()
خطا را دریافت کنید.اگر کاربر چندین عامل ثانویه را ثبت کرده است، از آنها بپرسید که از کدام یک استفاده کنند. می توانید شماره تلفن پوشانده شده را با
resolver.hints[selectedIndex].phoneNumber
و نام نمایش داده شده را باresolver.hints[selectedIndex].displayName
دریافت کنید.سویفت
// Ask user which second factor to use. Then: if resolver.hints[selectedIndex].factorID == PhoneMultiFactorID { // User selected a phone second factor. // ... } else if resolver.hints[selectedIndex].factorID == TotpMultiFactorID { // User selected a TOTP second factor. // ... } else { // Unsupported second factor. }
هدف-C
FIRMultiFactorResolver *resolver = (FIRMultiFactorResolver *) error.userInfo[FIRAuthErrorUserInfoMultiFactorResolverKey]; // Ask user which second factor to use. Then: FIRPhoneMultiFactorInfo *hint = (FIRPhoneMultiFactorInfo *) resolver.hints[selectedIndex]; if (hint.factorID == FIRPhoneMultiFactorID) { // User selected a phone second factor. // ... } else if (hint.factorID == FIRTOTPMultiFactorID) { // User selected a TOTP second factor. // ... } else { // Unsupported second factor. }
ارسال یک پیام تأیید به تلفن کاربر:
سویفت
// Send SMS verification code. let hint = resolver.hints[selectedIndex] as! PhoneMultiFactorInfo PhoneAuthProvider.provider().verifyPhoneNumber( with: hint, uiDelegate: nil, multiFactorSession: resolver.session ) { (verificationId, error) in // verificationId will be needed for sign-in completion. }
هدف-C
// Send SMS verification code [FIRPhoneAuthProvider.provider verifyPhoneNumberWithMultiFactorInfo:hint UIDelegate:nil multiFactorSession:resolver.session completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) { if (error != nil) { // Failed to verify phone number. } }];
پس از ارسال کد پیامک، از کاربر بخواهید تا کد را تأیید کند و از آن برای ساخت
PhoneAuthCredential
استفاده کند:سویفت
// Ask user for the verification code. Then: let credential = PhoneAuthProvider.provider().credential( withVerificationID: verificationId!, verificationCode: verificationCodeFromUser)
هدف-C
// Ask user for the SMS verification code. Then: FIRPhoneAuthCredential *credential = [FIRPhoneAuthProvider.provider credentialWithVerificationID:verificationID verificationCode:verificationCodeFromUser];
یک شیء ادعا را با اعتبار راه اندازی کنید:
سویفت
let assertion = PhoneMultiFactorGenerator.assertion(with: credential)
هدف-C
FIRMultiFactorAssertion *assertion = [FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
ورود به سیستم را حل کنید. سپس میتوانید به نتیجه ورود به سیستم اصلی، که شامل دادههای استاندارد خاص ارائهدهنده و اعتبارنامههای احراز هویت است، دسترسی پیدا کنید:
سویفت
// Complete sign-in. This will also trigger the Auth state listeners. resolver.resolveSignIn(with: assertion) { (authResult, error) in // authResult will also contain the user, additionalUserInfo, optional // credential (null for email/password) associated with the first factor sign-in. // For example, if the user signed in with Google as a first factor, // authResult.additionalUserInfo will contain data related to Google provider that // the user signed in with. // user.credential contains the Google OAuth credential. // user.credential.accessToken contains the Google OAuth access token. // user.credential.idToken contains the Google OAuth ID token. }
هدف-C
// Complete sign-in. [resolver resolveSignInWithAssertion:assertion completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { if (error != nil) { // User successfully signed in with the second factor phone number. } }];
کد زیر یک مثال کامل از ورود به یک کاربر چند عاملی را نشان می دهد:
سویفت
Auth.auth().signIn(
withEmail: email,
password: password
) { (result, error) in
let authError = error as NSError?
if authError?.code == AuthErrorCode.secondFactorRequired.rawValue {
let resolver =
authError!.userInfo[AuthErrorUserInfoMultiFactorResolverKey] as! MultiFactorResolver
// Ask user which second factor to use.
// ...
// Then:
let hint = resolver.hints[selectedIndex] as! PhoneMultiFactorInfo
// Send SMS verification code
PhoneAuthProvider.provider().verifyPhoneNumber(
with: hint,
uiDelegate: nil,
multiFactorSession: resolver.session
) { (verificationId, error) in
if error != nil {
// Failed to verify phone number.
}
// Ask user for the SMS verification code.
// ...
// Then:
let credential = PhoneAuthProvider.provider().credential(
withVerificationID: verificationId!,
verificationCode: verificationCodeFromUser)
let assertion = PhoneMultiFactorGenerator.assertion(with: credential)
// Complete sign-in.
resolver.resolveSignIn(with: assertion) { (authResult, error) in
if error != nil {
// User successfully signed in with the second factor phone number.
}
}
}
}
}
هدف-C
[FIRAuth.auth signInWithEmail:email
password:password
completion:^(FIRAuthDataResult * _Nullable authResult,
NSError * _Nullable error) {
if (error == nil || error.code != FIRAuthErrorCodeSecondFactorRequired) {
// User is not enrolled with a second factor and is successfully signed in.
// ...
} else {
FIRMultiFactorResolver *resolver =
(FIRMultiFactorResolver *) error.userInfo[FIRAuthErrorUserInfoMultiFactorResolverKey];
// Ask user which second factor to use.
// ...
// Then:
FIRPhoneMultiFactorInfo *hint = (FIRPhoneMultiFactorInfo *) resolver.hints[selectedIndex];
// Send SMS verification code
[FIRPhoneAuthProvider.provider
verifyPhoneNumberWithMultiFactorInfo:hint
UIDelegate:nil
multiFactorSession:resolver.session
completion:^(NSString * _Nullable verificationID,
NSError * _Nullable error) {
if (error != nil) {
// Failed to verify phone number.
}
// Ask user for the SMS verification code.
// ...
// Then:
FIRPhoneAuthCredential *credential =
[FIRPhoneAuthProvider.provider
credentialWithVerificationID:verificationID
verificationCode:kPhoneSecondFactorVerificationCode];
FIRMultiFactorAssertion *assertion =
[FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
// Complete sign-in.
[resolver resolveSignInWithAssertion:assertion
completion:^(FIRAuthDataResult * _Nullable authResult,
NSError * _Nullable error) {
if (error != nil) {
// User successfully signed in with the second factor phone number.
}
}];
}];
}
}];
تبریک می گویم! شما با موفقیت با استفاده از احراز هویت چند عاملی وارد حساب کاربری شده اید.
بعدش چی
- با Admin SDK ، کاربران چند عاملی را به صورت برنامهنویسی مدیریت کنید .