يمكنك السماح للمستخدمين بالمصادقة باستخدام Firebase من خلال مقدّمي خدمات OAuth، مثل GitHub، من خلال دمج ميزة تسجيل الدخول العامة عبر OAuth في تطبيقك باستخدام حزمة تطوير البرامج (SDK) لمنصّة Firebase بغرض تنفيذ عملية تسجيل الدخول من البداية إلى النهاية.
قبل البدء
لتسجيل دخول المستخدمين باستخدام حسابات GitHub، عليك أولاً تفعيل GitHub كمقدّم خدمات تسجيل دخول لمشروعك على Firebase:
استخدِم Swift Package Manager لتثبيت تبعيات Firebase وإدارتها.
- في Xcode، مع فتح مشروع تطبيقك، انتقِل إلى ملف > إضافة حِزم.
- أضِف مستودع حزمة تطوير البرامج (SDK) لمنصّات Apple من Firebase عندما يُطلب منك ذلك:
- اختَر مكتبة Firebase Authentication.
- أضِف العلامة
-ObjC
إلى قسم رموز ربط أخرى في إعدادات الإنشاء الخاصة بالهدف. - عند الانتهاء، سيبدأ Xcode تلقائيًا في حلّ ملفاتك المضمّنة وتنزيلها في الخلفية.
https://github.com/firebase/firebase-ios-sdk.git
الآن، عليك تنفيذ بعض خطوات الضبط:
- في وحدة تحكّم Firebase، افتح قسم Auth.
- في علامة التبويب طريقة تسجيل الدخول، فعِّل موفِّر GitHub.
- أضِف معرّف العميل وسر العميل من وحدة تحكّم المطوّر لدى موفِّر الخدمة إلى
إعدادات موفِّر الخدمة:
- سجِّل تطبيقك كتطبيق مطوّر على GitHub واحصل على معرِّف العميل وسر العميل لتطبيقك في OAuth 2.0.
- تأكَّد من ضبط معرّف الموارد المنتظم لإعادة التوجيه في بروتوكول OAuth (مثل
my-app-12345.firebaseapp.com/__/auth/handler
) في عنوان URL لطلب إعادة التفويض في صفحة إعدادات تطبيقك على إعدادات تطبيق GitHub.
- انقر على حفظ.
التعامل مع مسار تسجيل الدخول باستخدام حزمة تطوير البرامج (SDK) لمنصّة Firebase
لمعالجة عملية تسجيل الدخول باستخدام حزمة تطوير البرامج (SDK) لنظام Firebase على منصات Apple، اتّبِع الخطوات التالية:
أضِف مخطّطات عناوين URL مخصّصة إلى مشروعك على Xcode:
- افتح إعدادات المشروع: انقر نقرًا مزدوجًا على اسم المشروع في عرض الشجرة على يمين الصفحة. اختَر تطبيقك من قسم الاستهدافات، ثم انقر على علامة التبويب المعلومات ووسِّع قسم أنواع عناوين URL.
- انقر على الزر + وأضِف رقم تعريف التطبيق المشفَّر كتنسيق عنوان URL. يمكنك العثور على رقم تعريف التطبيق المشفَّر في صفحة
الإعدادات
العامة في وحدة تحكُّم Firebase، في قسم
تطبيقك على iOS. اترك الحقول الأخرى فارغة.
عند الانتهاء، من المفترض أن تظهر الإعدادات على النحو التالي (ولكن مع القيم الخاصة بتطبيقك):
أنشئ مثيلًا من OAuthProvider باستخدام معرّف مقدّم الخدمة github.com.
var provider = OAuthProvider(providerID: "github.com")
FIROAuthProvider *provider = [FIROAuthProvider providerWithProviderID:@"github.com"];
اختياري: حدِّد مَعلمات OAuth مخصّصة إضافية تريد إرسالها مع طلب OAuth.
provider.customParameters = [ "allow_signup": "false" ]
[provider setCustomParameters:@{@"allow_signup": @"false"}];
لمعرفة المَعلمات التي يتيح استخدامها، يُرجى الاطّلاع على مستندات GitHub OAuth. يُرجى العِلم أنّه لا يمكنك تمرير المَعلمات المطلوبة من Firebase باستخدام
setCustomParameters
. هذه المَعلمات هي client_id، redirect_uri، وresponse_type، وscope، وstate.اختياري: حدِّد نطاقات OAuth 2.0 الإضافية التي تريد طلبها من موفِّر المصادقة، والتي تتعدى الملف الشخصي الأساسي. إذا كان تطبيقك يحتاج إلى الوصول إلى بيانات المستخدمين الخاصة من واجهات برمجة التطبيقات GitHub API، عليك طلب أذونات للوصول إلى واجهات برمجة التطبيقات GitHub API ضمن أذونات واجهة برمجة التطبيقات في وحدة تحكّم مطوّري GitHub. يجب أن تكون نطاقات OAuth المطلوبة مطابقة تمامًا للنطاقات التي تم ضبطها مسبقًا في أذونات واجهة برمجة التطبيقات للتطبيق.
// Request read access to a user's email addresses. // This must be preconfigured in the app's API permissions. provider.scopes = ["user:email"]
// Request read access to a user's email addresses. // This must be preconfigured in the app's API permissions. [provider setScopes:@[@"user:email"]];
لمزيد من المعلومات، يُرجى الرجوع إلى مستندات نطاقات GitHub.
اختياري: إذا كنت تريد تخصيص طريقة عرض التطبيق لملف
SFSafariViewController
أوUIWebView
عند عرض reCAPTCHA للمستخدم، أنشئ فئة مخصّصة تتوافق مع بروتوكولAuthUIDelegate
، ثمّ أعِد توجيهها إلىcredentialWithUIDelegate
.يمكنك المصادقة باستخدام Firebase باستخدام كائن مزوّد OAuth.
provider.getCredentialWith(nil) { credential, error in if error != nil { // Handle error. } if credential != nil { Auth().signIn(with: credential) { authResult, error in if error != nil { // Handle error. } // User is signed in. // IdP data available in authResult.additionalUserInfo.profile. guard let oauthCredential = authResult.credential as? OAuthCredential else { return } // GitHub OAuth access token can also be retrieved by: // oauthCredential.accessToken // GitHub OAuth ID token can be retrieved by calling: // oauthCredential.idToken } } }
[provider getCredentialWithUIDelegate:nil completion:^(FIRAuthCredential *_Nullable credential, NSError *_Nullable error) { if (error) { // Handle error. } if (credential) { [[FIRAuth auth] signInWithCredential:credential completion:^(FIRAuthDataResult *_Nullable authResult, NSError *_Nullable error) { if (error) { // Handle error. } // User is signed in. // IdP data available in authResult.additionalUserInfo.profile. FIROAuthCredential *oauthCredential = (FIROAuthCredential *)authResult.credential; // GitHub OAuth access token can also be retrieved by: // oauthCredential.accessToken // GitHub OAuth ID token can be retrieved by calling: // oauthCredential.idToken }]; } }];
باستخدام رمز الوصول OAuth، يمكنك استدعاء GitHub API.
على سبيل المثال، للحصول على معلومات الملف الشخصي الأساسية، يمكنك طلب واجهة برمجة التطبيقات REST API، مع تمرير الرمز المميّز للوصول في رأس
Authorization
:https://api.github.com/user
في حين أنّ الأمثلة أعلاه تركّز على عمليات تسجيل الدخول، يمكنك أيضًا ربط مقدّم خدمة GitHub بمستخدم حالي. على سبيل المثال، يمكنك ربط عدة مقدّمي خدمات بالمستخدم نفسه، ما يتيح له تسجيل الدخول باستخدام أيّ منهما.
Auth().currentUser.link(withCredential: credential) { authResult, error in if error != nil { // Handle error. } // GitHub credential is linked to the current user. // IdP data available in authResult.additionalUserInfo.profile. // GitHub OAuth access token can also be retrieved by: // (authResult.credential as? OAuthCredential)?.accessToken // GitHub OAuth ID token can be retrieved by calling: // (authResult.credential as? OAuthCredential)?.idToken }
[[FIRAuth auth].currentUser linkWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { if (error) { // Handle error. } // GitHub credential is linked to the current user. // IdP data available in authResult.additionalUserInfo.profile. // GitHub OAuth access token is can also be retrieved by: // ((FIROAuthCredential *)authResult.credential).accessToken // GitHub OAuth ID token can be retrieved by calling: // ((FIROAuthCredential *)authResult.credential).idToken }];
يمكن استخدام النمط نفسه مع
reauthenticateWithCredential
الذي يمكن استخدامه لاسترداد بيانات اعتماد جديدة للعمليات الحسّاسة التي تتطلّب تسجيل الدخول مؤخرًا.Auth().currentUser.reauthenticateWithCredential(withCredential: credential) { authResult, error in if error != nil { // Handle error. } // User is re-authenticated with fresh tokens minted and // should be able to perform sensitive operations like account // deletion and email or password update. // IdP data available in result.additionalUserInfo.profile. // Additional OAuth access token is can also be retrieved by: // (authResult.credential as? OAuthCredential)?.accessToken // GitHub OAuth ID token can be retrieved by calling: // (authResult.credential as? OAuthCredential)?.idToken }
[[FIRAuth auth].currentUser reauthenticateWithCredential:credential completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { if (error) { // Handle error. } // User is re-authenticated with fresh tokens minted and // should be able to perform sensitive operations like account // deletion and email or password update. // IdP data available in result.additionalUserInfo.profile. // Additional OAuth access token is can also be retrieved by: // ((FIROAuthCredential *)authResult.credential).accessToken // GitHub OAuth ID token can be retrieved by calling: // ((FIROAuthCredential *)authResult.credential).idToken }];
التعامل مع أخطاء account-exists-with-different-credential
إذا فعّلت الإعداد حساب واحد لكل عنوان بريد إلكتروني في وحدة تحكّم Firebase،
عندما يحاول مستخدم تسجيل الدخول إلى مقدّم خدمة (مثل GitHub) باستخدام عنوان بريد إلكتروني سبق أن
تم استخدامه لمقدّم خدمة آخر لمستخدم Firebase (مثل Google)، يتم طرح الخطأ
FIRAuthErrorCodeAccountExistsWithDifferentCredential
مع عنصر
FIRAuthCredential
مؤقت (بيانات اعتماد GitHub). لإكمال عملية تسجيل الدخول إلى
المزوّد المقصود، على المستخدم تسجيل الدخول أولاً إلى المزوّد الحالي (Google) ثم الربط بحساب
FIRAuthCredential
السابق (بيانات اعتماد GitHub). سيظهر هذا الإجراء على النحو الموضّح أدناه:
// Sign-in with an OAuth credential. provider.getCredentialWith(nil) { credential, error in // An account with the same email already exists. if (error as NSError?)?.code == AuthErrorCode.accountExistsWithDifferentCredential.rawValue { // Get pending credential and email of existing account. let existingAcctEmail = (error! as NSError).userInfo[AuthErrorUserInfoEmailKey] as! String let pendingCred = (error! as NSError).userInfo[AuthErrorUserInfoUpdatedCredentialKey] as! AuthCredential // Lookup existing account identifier by the email. Auth.auth().fetchProviders(forEmail:existingAcctEmail) { providers, error in // Existing email/password account. if (providers?.contains(EmailAuthProviderID))! { // Existing password account for email. Ask user to provide the password of the // existing account. // Sign in with existing account. Auth.auth().signIn(withEmail:existingAcctEmail, password:password) { user, error in // Successfully signed in. if user != nil { // Link pending credential to account. Auth.auth().currentUser?.linkAndRetrieveData(with: pendingCred) { result, error in // ... } } } } } return } // Other errors. if error != nil { // handle the error. return } // Sign in with the credential. if credential != nil { Auth.auth().signInAndRetrieveData(with: credential!) { result, error in if error != nil { // handle the error. return } } } }
// Sign-in with an OAuth credential. [provider getCredentialWithUIDelegate:nil completion:^(FIRAuthCredential *_Nullable credential, NSError *_Nullable error) { // An account with the same email already exists. if (error.code == FIRAuthErrorCodeAccountExistsWithDifferentCredential) { // Get pending credential and email of existing account. NSString *existingAcctEmail = error.userInfo[FIRAuthErrorUserInfoEmailKey]; FIRAuthCredential *pendingCred = error.userInfo[FIRAuthErrorUserInfoUpdatedCredentialKey]; // Lookup existing account identifier by the email. [[FIRAuth auth] fetchProvidersForEmail:existingAcctEmail completion:^(NSArray<NSString *> *_Nullable providers, NSError *_Nullable error) { // Existing email/password account. if ( [providers containsObject:FIREmailAuthProviderID] ) { // Existing password account for email. Ask user to provide the password of the // existing account. // Sign in with existing account. [[FIRAuth auth] signInWithEmail:existingAcctEmail password:password completion:^(FIRUser *user, NSError *error) { // Successfully signed in. if (user) { // Link pending credential to account. [[FIRAuth auth].currentUser linkWithCredential:pendingCred completion:^(FIRUser *_Nullable user, NSError *_Nullable error) { // ... }]; } }]; } }]; return; } // Other errors. if (error) { // handle the error. return; } // Sign in with the credential. if (credential) { [[FIRAuth auth] signInAndRetrieveDataWithCredential:credential completion:^(FIRAuthDataResult *_Nullable authResult, NSError *_Nullable error) { if (error) { // handle the error. return; } }]; } }];
الخطوات التالية
بعد أن يسجّل المستخدم الدخول لأول مرة، يتم إنشاء حساب مستخدم جديد وربطه ببيانات الاعتماد التي استخدمها المستخدم لتسجيل الدخول، أي اسم المستخدم وكلمة المرور أو رقم الهاتف أو معلومات مقدّم خدمة المصادقة. يتم تخزين هذا الحساب الجديد كجزء من مشروعك على Firebase، ويمكن استخدامه لتحديد هوية مستخدم في كل تطبيق في مشروعك، بغض النظر عن طريقة تسجيل دخول المستخدم.
-
في تطبيقاتك، يمكنك الحصول على معلومات الملف الشخصي الأساسية للمستخدم من العنصر
User
. راجِع إدارة المستخدمين. في Firebase Realtime Database وCloud Storage قواعد الأمان، يمكنك الحصول على معرّف المستخدم الفريد للمستخدم الذي سجّل الدخول من متغيّر
auth
، واستخدامه للتحكّم في البيانات التي يمكن للمستخدم الوصول إليها.
يمكنك السماح للمستخدمين بتسجيل الدخول إلى تطبيقك باستخدام عدة موفّري مصادقة من خلال ربط بيانات اعتماد موفّر المصادقة بحساب مستخدمحالٍ.
لتسجيل خروج مستخدم، اتصل بالرقم
signOut:
.
let firebaseAuth = Auth.auth() do { try firebaseAuth.signOut() } catch let signOutError as NSError { print("Error signing out: %@", signOutError) }
NSError *signOutError; BOOL status = [[FIRAuth auth] signOut:&signOutError]; if (!status) { NSLog(@"Error signing out: %@", signOutError); return; }
يمكنك أيضًا إضافة رمز لمعالجة الأخطاء في النطاق الكامل لأخطاء مصادقة العميل. راجِع مقالة معالجة الأخطاء.