Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

المصادقة باستخدام Apple و C ++

يمكنك السماح للمستخدمين بالمصادقة مع Firebase باستخدام معرف Apple الخاص بهم باستخدام Firebase SDK لتنفيذ تدفق تسجيل الدخول من طرف إلى طرف OAuth 2.0.

قبل ان تبدأ

لتسجيل دخول المستخدمين باستخدام Apple ، قم أولاً بتكوين Sign In with Apple على موقع مطوري Apple ، ثم قم بتمكين Apple كموفر تسجيل الدخول لمشروع Firebase الخاص بك.

انضم إلى برنامج Apple Developer Program

تسجيل الدخول مع يمكن تكوين أبل فقط من قبل أعضاء المطور أبل برنامج .

قم بتكوين تسجيل الدخول مع Apple

يجب تمكين Apple Sign In وتكوينه بشكل صحيح في مشروع Firebase الخاص بك. يختلف التكوين عبر منصات Android و iOS. يرجى اتباع "تكوين تسجيل الدخول مع أبل" قسم من دائرة الرقابة الداخلية و / أو الروبوت أدلة قبل المتابعة.

قم بتمكين Apple كموفر لتسجيل الدخول

  1. في وحدة التحكم Firebase ، فتح الباب أصيل. على علامة التبويب تسجيل الدخول الأسلوب، تمكين مزود أبل.
  2. قم بتكوين إعدادات موفر خدمة تسجيل الدخول من Apple:
    1. إذا كنت تنشر تطبيقك على iOS فقط ، فيمكنك ترك معرف الخدمة ومعرف فريق Apple والمفتاح الخاص وحقول معرف المفتاح فارغة.
    2. للدعم على أجهزة Android:
      1. إضافة Firebase إلى مشروع Android . تأكد من تسجيل توقيع SHA-1 لتطبيقك عند إعداد تطبيقك في وحدة تحكم Firebase.
      2. في وحدة التحكم Firebase ، فتح الباب أصيل. على علامة التبويب تسجيل الدخول الأسلوب، تمكين مزود أبل. حدد معرّف الخدمة الذي أنشأته في القسم السابق. أيضًا ، في قسم تكوين تدفق كود OAuth ، حدد معرف فريق Apple الخاص بك والمفتاح الخاص ومعرف المفتاح اللذين أنشأتهما في القسم السابق.

الامتثال لمتطلبات البيانات المجهولة الهوية من Apple

تسجيل الدخول مع أبل تتيح للمستخدمين خيار إخفاء الهوية البيانات الخاصة بهم، بما في ذلك عناوين بريدهم الإلكتروني، عند تسجيل الدخول. المستخدمين الذين يختارون هذا الخيار يكون عناوين البريد الإلكتروني مع المجال privaterelay.appleid.com . عند استخدام تسجيل الدخول مع Apple في تطبيقك ، يجب عليك الامتثال لأي سياسات مطور أو شروط مطبقة من Apple فيما يتعلق بمعرفات Apple المجهولة الهوية.

يتضمن ذلك الحصول على أي موافقة مطلوبة من المستخدم قبل ربط أي معلومات شخصية تحدد الهوية مباشرة بمعرف Apple المجهول. عند استخدام مصادقة Firebase ، قد يشمل ذلك الإجراءات التالية:

  • اربط عنوان بريد إلكتروني بمعرف Apple المجهول أو العكس.
  • اربط رقم هاتف بمعرف Apple المجهول أو العكس
  • اربط بيانات اعتماد اجتماعية غير مجهولة (Facebook و Google وما إلى ذلك) بمعرف Apple المجهول أو العكس.

القائمة أعلاه ليست شاملة. راجع اتفاقية ترخيص برنامج مطوري Apple في قسم العضوية لحساب المطور الخاص بك للتأكد من أن تطبيقك يلبي متطلبات Apple.

الوصول إلى firebase::auth::Auth الطبقة

في Auth الفئة هي بوابة لجميع المكالمات API.
  1. إضافة الملفات رأس مصادقة والتطبيق:
    #include "firebase/app.h"
    #include "firebase/auth.h"
    
  2. في رمز التهيئة الخاص بك، قم بإنشاء firebase::App الطبقة.
    #if defined(__ANDROID__)
      firebase::App* app =
          firebase::App::Create(firebase::AppOptions(), my_jni_env, my_activity);
    #else
      firebase::App* app = firebase::App::Create(firebase::AppOptions());
    #endif  // defined(__ANDROID__)
    
  3. الحصول على firebase::auth::Auth الطبقة الخاصة بك firebase::App . هناك تعيين واحد الى واحد بين App و Auth .
    firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);
    

تعامل مع تدفق تسجيل الدخول باستخدام Firebase SDK

تختلف عملية تسجيل الدخول باستخدام Apple عبر منصات iOS و Android.

على نظام iOS

قم بمصادقة المستخدمين باستخدام Firebase عبر Apple Sign In Objective-C SDK الذي تم استدعاؤه من كود C ++ الخاص بك.

  1. لكل طلب تسجيل دخول ، أنشئ سلسلة عشوائية - "nonce" - والتي ستستخدمها للتأكد من أن رمز المعرف المميز الذي تحصل عليه قد تم منحه استجابةً لطلب مصادقة التطبيق الخاص بك على وجه التحديد. هذه الخطوة مهمة لمنع هجمات الإعادة.

      - (NSString *)randomNonce:(NSInteger)length {
        NSAssert(length > 0, @"Expected nonce to have positive length");
        NSString *characterSet = @"0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._";
        NSMutableString *result = [NSMutableString string];
        NSInteger remainingLength = length;
    
        while (remainingLength > 0) {
          NSMutableArray *randoms = [NSMutableArray arrayWithCapacity:16];
          for (NSInteger i = 0; i < 16; i++) {
            uint8_t random = 0;
            int errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random);
            NSAssert(errorCode == errSecSuccess, @"Unable to generate nonce: OSStatus %i", errorCode);
    
            [randoms addObject:@(random)];
          }
    
          for (NSNumber *random in randoms) {
            if (remainingLength == 0) {
              break;
            }
    
            if (random.unsignedIntValue < characterSet.length) {
              unichar character = [characterSet characterAtIndex:random.unsignedIntValue];
              [result appendFormat:@"%C", character];
              remainingLength--;
            }
          }
        }
      }
    
    

    سترسل تجزئة SHA256 لـ nonce مع طلب تسجيل الدخول ، والذي ستمرره Apple دون تغيير في الاستجابة. يتحقق Firebase من الاستجابة عن طريق تجزئة الرقم الأصلي غير القياسي ومقارنته بالقيمة التي تم تمريرها بواسطة Apple.

  2. ابدأ تدفق تسجيل الدخول إلى Apple ، بما في ذلك في طلبك تجزئة SHA256 لفئة nonce وفئة المفوض التي ستتعامل مع استجابة Apple (راجع الخطوة التالية):

      - (void)startSignInWithAppleFlow {
        NSString *nonce = [self randomNonce:32];
        self.currentNonce = nonce;
        ASAuthorizationAppleIDProvider *appleIDProvider = [[ASAuthorizationAppleIDProvider alloc] init];
        ASAuthorizationAppleIDRequest *request = [appleIDProvider createRequest];
        request.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];
        request.nonce = [self stringBySha256HashingString:nonce];
    
        ASAuthorizationController *authorizationController =
            [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]];
        authorizationController.delegate = self;
        authorizationController.presentationContextProvider = self;
        [authorizationController performRequests];
      }
    
      - (NSString *)stringBySha256HashingString:(NSString *)input {
        const char *string = [input UTF8String];
        unsigned char result[CC_SHA256_DIGEST_LENGTH];
        CC_SHA256(string, (CC_LONG)strlen(string), result);
    
        NSMutableString *hashed = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
        for (NSInteger i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
          [hashed appendFormat:@"%02x", result[i]];
        }
        return hashed;
      }
    
  3. تعامل مع استجابة Apple في تنفيذك لـ ASAuthorizationControllerDelegate`. إذا كان تسجيل الدخول ناجحًا ، فاستخدم رمز المعرف المميز من استجابة Apple مع nonce غير المجزأ للمصادقة مع Firebase:

      - (void)authorizationController:(ASAuthorizationController *)controller
         didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0)) {
        if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
          ASAuthorizationAppleIDCredential *appleIDCredential = authorization.credential;
          NSString *rawNonce = self.currentNonce;
          NSAssert(rawNonce != nil, @"Invalid state: A login callback was received, but no login request was sent.");
    
          if (appleIDCredential.identityToken == nil) {
            NSLog(@"Unable to fetch identity token.");
            return;
          }
    
          NSString *idToken = [[NSString alloc] initWithData:appleIDCredential.identityToken
                                                    encoding:NSUTF8StringEncoding];
          if (idToken == nil) {
            NSLog(@"Unable to serialize id token from data: %@", appleIDCredential.identityToken);
          }
        }
    
  4. استخدم سلسلة الرمز المميز الناتجة و nonce الأصلي لإنشاء بيانات اعتماد Firebase وتسجيل الدخول إلى Firebase.

    firebase::auth::OAuthProvider::GetCredential(
            /*provider_id=*/"apple.com", token, nonce,
            /*access_token=*/nullptr);
    
    firebase::Future<firebase::auth::User*> result =
        auth->SignInWithCredential(credential);
    
  5. على نفس النمط يمكن استخدامها مع Reauthenticate والتي يمكن استخدامها لاسترداد أوراق اعتماد جديدة لعمليات الحساسة التي تتطلب تسجيل الدخول مؤخرا.

    firebase::Future<firebase::auth::SignInResult> result =
        user->Reauthenticate(credential);
    
  6. يمكن استخدام نفس النمط لربط حساب بـ Apple Sign In. ومع ذلك ، قد تواجه خطأ عند ربط حساب Firebase موجود بالفعل بحساب Apple الذي تحاول الارتباط به. وعندما يحدث هذا في المستقبل سيعود حالة من kAuthErrorCredentialAlreadyInUse والكائن المعلومات حول المستخدم من SignInResult قد تحتوي على صالح updated_credential . هذا الاعتماد يمكن استخدامه لتسجيل الدخول إلى الحساب المرتبط أبل عبر SignInWithCredential دون الحاجة لتوليد آخر تسجيل أبل في رمز وحالية.

    لاحظ أنه يجب استخدام LinkAndRetrieveDataWithCredential لهذه العملية لاحتواء الاعتماد كما updated_credential هو عضو في SignInResult.UserInfo الكائن.

    firebase::Future<firebase::auth::SignInResult> link_result =
        auth->current_user()->LinkAndRetrieveDataWithCredential(credential);
    
    // To keep example simple, wait on the current thread until call completes.
    while (link_result.status() == firebase::kFutureStatusPending) {
      Wait(100);
    }
    
    // Determine the result of the link attempt
    if (link_result.error() == firebase::auth::kAuthErrorNone) {
      // user linked correctly.
    } else if (link_result.error() ==
                   firebase::auth::kAuthErrorCredentialAlreadyInUse &&
               link_result.result()->info.updated_credential.is_valid()) {
      // Sign In with the new credential
      firebase::Future<firebase::auth::User*> result = auth->SignInWithCredential(
          link_result.result()->info.updated_credential);
    } else {
      // Another link error occurred.
    }
    

على Android

على Android ، قم بمصادقة المستخدمين باستخدام Firebase من خلال دمج تسجيل دخول OAuth العام المستند إلى الويب في تطبيقك باستخدام Firebase SDK لتنفيذ تدفق تسجيل الدخول من البداية إلى النهاية.

للتعامل مع تدفق تسجيل الدخول باستخدام Firebase SDK ، اتبع الخطوات التالية:

  1. بناء مثيل FederatedOAuthProviderData تكوينه مع المناسبة ID مزود لشركة آبل.

    firebase::auth::FederatedOAuthProviderData provider_data("apple.com");
    
  2. اختياري: حدد أوث إضافي 2.0 نطاقات خارج الافتراضي الذي تريد طلب من مزود المصادقة.

    provider_data.scopes.push_back("email");
    provider_data.scopes.push_back("name");
    
  3. اختياري: إذا كنت ترغب في عرض تسجيل الدخول أبل الشاشة في لغة أخرى غير الإنجليزية، تعيين locale المعلمة. انظر تسجيل الدخول مع مستندات أبل لغات معتمدة.

    // Localize to French.
    provider_data.custom_parameters["language"] = "fr";
    ```
    
  4. بمجرد تكوين بيانات الموفر ، استخدمها لإنشاء FederatedOAuthProvider.

    // Construct a FederatedOAuthProvider for use in Auth methods.
    firebase::auth::FederatedOAuthProvider provider(provider_data);
    
  5. مصادقة مع Firebase باستخدام كائن موفر المصادقة. لاحظ أنه على عكس عمليات FirebaseAuth الأخرى ، فإن هذا سيتحكم في واجهة المستخدم الخاصة بك عن طريق ظهور عرض ويب يمكن للمستخدم من خلاله إدخال بيانات الاعتماد الخاصة به.

    لبدء تسجيل الدخول التدفق، وندعو signInWithProvider :

    firebase::Future<firebase::auth::SignInResult> result =
      auth->SignInWithProvider(provider_data);
    

    قد التطبيق الخاص بك، ثم الانتظار أو تسجيل الاستدعاء في المستقبل .

  6. على نفس النمط يمكن استخدامها مع ReauthenticateWithProvider والتي يمكن استخدامها لاسترداد أوراق اعتماد جديدة لعمليات الحساسة التي تتطلب تسجيل الدخول مؤخرا.

    firebase::Future<firebase::auth::SignInResult> result =
      user->ReauthenticateWithProvider(provider_data);
    

    قد التطبيق الخاص بك، ثم الانتظار أو تسجيل الاستدعاء في المستقبل .

  7. و، يمكنك استخدام linkWithCredential() لربط مقدمي هوية مختلفة لحسابات القائمة.

    لاحظ أن Apple تطلب منك الحصول على موافقة صريحة من المستخدمين قبل ربط حسابات Apple الخاصة بهم ببيانات أخرى.

    على سبيل المثال ، لربط حساب Facebook بحساب Firebase الحالي ، استخدم رمز الوصول الذي حصلت عليه من تسجيل دخول المستخدم إلى Facebook:

    // Initialize a Facebook credential with a Facebook access token.
    AuthCredential credential =
        firebase::auth::FacebookAuthProvider.getCredential(token);
    
    // Assuming the current user is an Apple user linking a Facebook provider.
    firebase::Future<firebase::auth::SignInResult> result =
        auth.getCurrentUser().linkWithCredential(credential);
    

قم بتسجيل الدخول باستخدام Apple Notes

على عكس الموفرين الآخرين المدعومين بواسطة Firebase Auth ، لا تقدم Apple عنوان URL للصورة.

أيضا، عندما يختار المستخدم ليس لتبادل البريد الإلكتروني الخاصة بهم مع التطبيق، أحكام أبل عنوان بريد إلكتروني فريد لهذا المستخدم (النموذج xyz@privaterelay.appleid.com )، وهو ما أسهم مع التطبيق الخاص بك. إذا قمت بتكوين خدمة ترحيل البريد الإلكتروني الخاص ، فإن Apple تعيد توجيه رسائل البريد الإلكتروني المرسلة إلى العنوان المجهول إلى عنوان البريد الإلكتروني الحقيقي للمستخدم.

التفاح المعلومات سهم فقط المستخدم مثل اسم العرض مع التطبيقات أول مرة قيام المستخدم بتسجيل الدخول. عادة، Firebase مخازن اسم العرض أول مرة قيام المستخدم بتسجيل الدخول مع أبل، والتي يمكنك الحصول عليها مع getCurrentUser().getDisplayName() . ومع ذلك ، إذا سبق لك استخدام Apple لتسجيل دخول مستخدم إلى التطبيق دون استخدام Firebase ، فلن تقدم Apple اسم عرض المستخدم لـ Firebase.

الخطوات التالية

بعد أن يقوم المستخدم بتسجيل الدخول لأول مرة ، يتم إنشاء حساب مستخدم جديد وربطه ببيانات الاعتماد - أي اسم المستخدم وكلمة المرور أو رقم الهاتف أو معلومات موفر المصادقة - المستخدم الذي قام بتسجيل الدخول باستخدام. يتم تخزين هذا الحساب الجديد كجزء من مشروع Firebase الخاص بك ، ويمكن استخدامه لتحديد هوية مستخدم عبر كل تطبيق في مشروعك ، بغض النظر عن كيفية تسجيل المستخدم للدخول.

في تطبيقاتك ، يمكنك الحصول على معلومات الملف الشخصي الأساسية للمستخدم من Firebase :: auth :: user object. انظر إدارة المستخدمين .

في قاعدة بيانات Firebase Realtime وقواعد أمان التخزين السحابي ، يمكنك الحصول على معرف المستخدم الفريد للمستخدم الذي قام بتسجيل الدخول من متغير المصادقة ، واستخدامه للتحكم في البيانات التي يمكن للمستخدم الوصول إليها.