المصادقة باستخدام Twitter على أنظمة Apple الأساسية

يمكنك السماح للمستخدِمين بالمصادقة باستخدام Firebase من خلال مقدّمي خدمة OAuth، مثل Twitter، وذلك من خلال دمج ميزة تسجيل الدخول العامة عبر OAuth في تطبيقك باستخدام حزمة تطوير البرامج (SDK) لمنصّة Firebase بهدف تنفيذ عملية تسجيل الدخول من البداية إلى النهاية.

قبل البدء

استخدِم Swift Package Manager لتثبيت تبعيات Firebase وإدارتها.

  1. في Xcode، مع فتح مشروع تطبيقك، انتقِل إلى ملف > إضافة حِزم.
  2. أضِف مستودع حزمة تطوير البرامج (SDK) لمنصّات Apple من Firebase عندما يُطلب منك ذلك:
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. اختَر مكتبة Firebase Authentication.
  5. أضِف العلامة -ObjC إلى قسم رموز ربط أخرى في إعدادات الإنشاء الخاصة بالهدف.
  6. عند الانتهاء، سيبدأ Xcode تلقائيًا في حلّ ملفاتك المضمّنة وتنزيلها في الخلفية.

لتسجيل دخول المستخدمين باستخدام حسابات Twitter، عليك أولاً تفعيل Twitter كمقدّم خدمات تسجيل دخول لمشروعك على Firebase:

  1. أضِف Firebase إلى مشروعك على Apple.

  2. أدرِج مجموعات الإعلانات المتسلسلة التالية في Podfile:

    pod 'FirebaseAuth'
  3. في وحدة تحكّم Firebase، افتح قسم Auth.
  4. في علامة التبويب طريقة تسجيل الدخول، فعِّل موفِّر Twitter.
  5. أضِف مفتاح واجهة برمجة التطبيقات وسر واجهة برمجة التطبيقات من وحدة تحكُّم المطوّر لدى موفِّر الخدمة إلى إعدادات موفِّر الخدمة:
    1. سجِّل تطبيقك كتطبيق مطوّر على Twitter واحصل على مفتاح واجهة برمجة التطبيقات ومفتاح سر واجهة برمجة التطبيقات لتطبيقك المزوّد ببروتوكول OAuth.
    2. تأكَّد من ضبط عنوان URL لإعادة التوجيه في OAuth (مثل my-app-12345.firebaseapp.com/__/auth/handler) في Firebase على أنّه عنوان URL لطلب إعادة التفويض في صفحة إعدادات تطبيقك ضمن إعدادات تطبيق Twitter.
  6. انقر على حفظ.

التعامل مع مسار تسجيل الدخول باستخدام حزمة تطوير البرامج (SDK) لمنصّة Firebase

لمعالجة عملية تسجيل الدخول باستخدام حزمة تطوير البرامج (SDK) لنظام Firebase على منصات Apple، اتّبِع الخطوات التالية:

  1. أضِف مخطّطات عناوين URL مخصّصة إلى مشروعك على Xcode:

    1. افتح إعدادات المشروع: انقر نقرًا مزدوجًا على اسم المشروع في عرض الشجرة على يمين الصفحة. اختَر تطبيقك من قسم الاستهدافات، ثم انقر على علامة التبويب المعلومات ووسِّع قسم أنواع عناوين URL.
    2. انقر على الزر + وأضِف رقم تعريف التطبيق المشفَّر كتنسيق عنوان URL. يمكنك العثور على رقم تعريف التطبيق المشفَّر في صفحة الإعدادات العامة في وحدة تحكُّم Firebase، في قسم تطبيقك على iOS. اترك الحقول الأخرى فارغة.

      عند الانتهاء، من المفترض أن تظهر الإعدادات على النحو التالي (ولكن مع القيم الخاصة بتطبيقك):

      لقطة شاشة لواجهة إعداد مخطّط عنوان URL المخصّص في Xcode

  2. أنشئ مثيلًا من OAuthProvider باستخدام معرّف مقدّم الخدمة twitter.com.

    SwiftObjective-C
        var provider = OAuthProvider(providerID: "twitter.com")
        
        FIROAuthProvider *provider = [FIROAuthProvider providerWithProviderID:@"twitter.com"];
        
  3. اختياري: حدِّد مَعلمات OAuth مخصّصة إضافية تريد إرسالها مع طلب OAuth.

    SwiftObjective-C
        provider.customParameters = [
          "lang": "fr"
          ]
        
        [provider setCustomParameters:@{@"lang": @"fr"}];
        

    لمعرفة المَعلمات التي يتيح استخدامها على Twitter، يُرجى الاطّلاع على مستندات Twitter OAuth. يُرجى العِلم أنّه لا يمكنك تمرير المَعلمات المطلوبة من Firebase باستخدام setCustomParameters. هذه المَعلمات هي client_id، redirect_uri، وresponse_type، وscope، وstate.

  4. اختياري: إذا كنت تريد تخصيص طريقة عرض التطبيق لملف SFSafariViewController أو UIWebView عند عرض reCAPTCHA للمستخدم، أنشئ فئة مخصّصة تتوافق مع بروتوكول AuthUIDelegate، ثمّ أعِد توجيهها إلى credentialWithUIDelegate.

  5. يمكنك المصادقة باستخدام Firebase باستخدام كائن مزوّد OAuth.

    SwiftObjective-C
        provider.getCredentialWith(nil) { credential, error in
          if error != nil {
            // Handle error.
          }
          if credential != nil {
            Auth.auth().signIn(with: credential) { authResult, error in
              if error != nil {
                // Handle error.
              }
              // User is signed in.
              // IdP data available in authResult.additionalUserInfo.profile.
              // Twitter OAuth access token can also be retrieved by:
              // (authResult.credential as? OAuthCredential)?.accessToken
              // Twitter OAuth ID token can be retrieved by calling:
              // (authResult.credential as? OAuthCredential)?.idToken
              // Twitter OAuth secret can be retrieved by calling:
              // (authResult.credential as? OAuthCredential)?.secret
            }
          }
        }
        
        [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.
              // Twitter OAuth access token can also be retrieved by:
              // authResult.credential.accessToken
              // Twitter OAuth ID token can be retrieved by calling:
              // authResult.credential.idToken
              // Twitter OAuth secret can be retrieved by calling:
              // authResult.credential.secret
            }];
          }
        }];
        

    باستخدام رمز الوصول OAuth، يمكنك طلب Twitter API.

    على سبيل المثال، للحصول على معلومات الملف الشخصي الأساسية، يمكنك طلب واجهة برمجة التطبيقات REST API، مع تمرير الرمز المميّز للوصول في رأس Authorization:

    https://api.twitter.com/labs/1/users?usernames=TwitterDev
  6. في حين أنّ الأمثلة أعلاه تركّز على عمليات تسجيل الدخول، يمكنك أيضًا ربط مقدّم خدمة Twitter بمستخدم حالي. على سبيل المثال، يمكنك ربط عدة مقدّمي خدمات بالمستخدم نفسه، ما يتيح له تسجيل الدخول باستخدام أيّ منهما.

    SwiftObjective-C
        Auth().currentUser.link(withCredential: credential) { authResult, error in
          if error != nil {
            // Handle error.
          }
          // Twitter credential is linked to the current user.
          // IdP data available in authResult.additionalUserInfo.profile.
          // Twitter OAuth access token can also be retrieved by:
          // (authResult.credential as? OAuthCredential)?.accessToken
          // Twitter OAuth ID token can be retrieved by calling:
          // (authResult.credential as? OAuthCredential)?.idToken
          // Twitter OAuth secret can be retrieved by calling:
          // (authResult.credential as? OAuthCredential)?.secret
        }
        
        [[FIRAuth auth].currentUser
            linkWithCredential:credential
                    completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
          if (error) {
            // Handle error.
          }
          // Twitter credential is linked to the current user.
          // IdP data available in authResult.additionalUserInfo.profile.
          // Twitter OAuth access token is can also be retrieved by:
          // ((FIROAuthCredential *)authResult.credential).accessToken
          // Twitter OAuth ID token can be retrieved by calling:
          // ((FIROAuthCredential *)authResult.credential).idToken
          // Twitter OAuth secret can be retrieved by calling:
          // ((FIROAuthCredential *)authResult.credential).secret
        }];
        
  7. يمكن استخدام النمط نفسه مع reauthenticateWithCredential الذي يمكن استخدامه لاسترداد بيانات اعتماد جديدة للعمليات الحسّاسة التي تتطلّب تسجيل الدخول مؤخرًا.

    SwiftObjective-C
        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
          // Twitter OAuth ID token can be retrieved by calling:
          // (authResult.credential as? OAuthCredential)?.idToken
          // Twitter OAuth secret can be retrieved by calling:
          // (authResult.credential as? OAuthCredential)?.secret
        }
        
        [[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
          // Twitter OAuth ID token can be retrieved by calling:
          // ((FIROAuthCredential *)authResult.credential).idToken
          // Twitter OAuth secret can be retrieved by calling:
          // ((FIROAuthCredential *)authResult.credential).secret
        }];
        

إذا فعّلت الإعداد حساب واحد لكل عنوان بريد إلكتروني في وحدة تحكّم Firebase، عندما يحاول مستخدم تسجيل الدخول إلى مقدّم خدمة (مثل Twitter) باستخدام عنوان بريد إلكتروني سبق أن تم استخدامه لمقدّم خدمة آخر لمستخدم Firebase (مثل Google)، يتم طرح الخطأ FIRAuthErrorCodeAccountExistsWithDifferentCredential مع عنصر FIRAuthCredential مؤقت (بيانات اعتماد Twitter). لإكمال عملية تسجيل الدخول إلى المزوّد المقصود، على المستخدم تسجيل الدخول أولاً إلى المزوّد الحالي (Google) ثم الربط بحساب FIRAuthCredential السابق (بيانات اعتماد Twitter). سيظهر هذا الإجراء على النحو الموضّح أدناه:

SwiftObjective-C
  // 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:.

SwiftObjective-C
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;
}

يمكنك أيضًا إضافة رمز لمعالجة الأخطاء في النطاق الكامل لأخطاء مصادقة العميل. راجِع مقالة معالجة الأخطاء.