אימות באמצעות Apple ו- C ++

אתה יכול לאפשר למשתמשים לבצע אימות באמצעות Firebase באמצעות מזהה Apple שלהם באמצעות Firebase SDK לביצוע זרימת הכניסה מקצה לקצה OAuth 2.0.

לפני שאתה מתחיל

כדי להיכנס למשתמשים באמצעות Apple, ראשית הגדר את כניסה באמצעות Apple באתר המפתחים של Apple, ואז הפעל את Apple כספקית כניסה לפרויקט Firebase שלך.

הצטרף לתוכנית המפתחים של אפל

היכנס עם אפל יכול להיות מוגדר רק על ידי חברי המפתחים של אפל תוכנית .

הגדר כניסה באמצעות Apple

על כניסה של Apple להיות מופעלת ולהגדיר כראוי בפרויקט Firebase שלך. התצורה משתנה בין פלטפורמות Android ו- iOS. בצע את "סימן Configure בשינה עם אפל" קטע iOS ו / או Android המדריכים לפני שתמשיך.

אפשר את אפל כספקית כניסה

  1. בשנות ה קונסולת Firebase , פתח את הקטע המחבר. 'הכניסה דרך כרטיסיית שיטה, לאפשר הספק האפל.
  2. הגדר את הגדרות ספק הכניסה של Apple:
    1. אם אתה פורס את האפליקציה שלך רק ב- iOS, אתה יכול להשאיר את שדות מזהה השירות, מזהה צוות Apple, המפתח הפרטי ומזהה המפתח ריקים.
    2. לתמיכה במכשירי Android:
      1. להוסיף Firebase לפרויקט Android שלך . הקפד לרשום את חתימת SHA-1 של האפליקציה שלך כאשר אתה מגדיר את האפליקציה שלך במסוף Firebase.
      2. בשנות ה קונסולת Firebase , פתח את הקטע המחבר. 'הכניסה דרך כרטיסיית שיטה, לאפשר הספק האפל. ציין את מזהה השירות שיצרת בסעיף הקודם. כמו כן, בקטע תצורת זרימת קוד OAuth, ציין את מזהה Apple Team שלך ואת המפתח הפרטי ומזהה המפתח שיצרת בסעיף הקודם.

ציית לדרישות הנתונים האנונימיות של Apple

היכנס עם אפל מעניקה למשתמשים את האפשרות של שהפיכת הנתונים שלהם, כולל כתובת הדוא"ל שלהם, בעת הכניסה. משתמשים שיבחרו באפשרות זו יש כתובות דוא"ל עם תחום privaterelay.appleid.com . כאשר אתה משתמש בכניסה עם Apple באפליקציה שלך, עליך לציית לכל מדיניות התנאים או התנאים הרלוונטיים של Apple בנוגע למזהי Apple אנונימיים אלה.

זה כולל קבלת כל הסכמת משתמש נדרשת לפני שתשייך מידע אישי המזהה ישירות עם מזהה אפל אנונימי. בעת שימוש באימות Firebase, הדבר עשוי לכלול את הפעולות הבאות:

  • קישור כתובת דוא"ל לתעודת מזהה אפל אנונימית או להיפך.
  • קשר מספר טלפון למזהה אפל אנונימי או להיפך
  • קשר אישורים חברתיים לא אנונימיים (פייסבוק, גוגל וכו ') לתעודת מזהה אפל אנונימית או להיפך.

הרשימה שלעיל אינה ממצה. עיין בהסכם הרישיון של תוכנית המפתחים של אפל בחלק החברות בחשבון המפתח שלך כדי לוודא שהאפליקציה שלך עומדת בדרישות של אפל.

גש firebase::auth::Auth בכיתה

Auth בכיתה היא השער עבור כל השיחות API.
  1. מוסיפים את קבצי הכותרת המחבר ואת App:
    #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);
    

לטפל בזרימת הכניסה באמצעות SDK של Firebase

תהליך הכניסה עם 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 עם בקשת הכניסה שלך, שאפל תעביר ללא שינוי בתגובה. Firebase מאמת את התגובה על ידי גיבוב של ה- nonce המקורי ומשווה אותו לערך שהועברה על ידי אפל.

  2. התחל את זרימת הכניסה של אפל, כולל בבקשתך את ה- Hash של SHA256 של ה- nonce ושל מחלקת הנציגים שתטפל בתגובת אפל (ראה את השלב הבא):

      - (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. טפל בתגובת אפל ביישום ASAuthorizationControllerDelegate שלך. אם הכניסה הצליחה, השתמש באסימון הזיהוי מהתגובה של אפל עם ה- 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 לבין אובייקט UserInfo של 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, אמת את המשתמשים שלך באמצעות Firebase על ידי שילוב כניסה OAuth כללית מבוססת אינטרנט באפליקציה שלך באמצעות SDK של Firebase כדי לבצע את זרימת הכניסה הקצה לסוף.

כדי לטפל בזרימת הכניסה עם SDK של Firebase, בצע את הצעדים הבאים:

  1. בניית מופע של FederatedOAuthProviderData מוגדר עם המתאים מזהה ספק עבור אפל.

    firebase::auth::FederatedOAuthProviderData provider_data("apple.com");
    
  2. אופציונאלי: ציין OAuth נוסף 2.0 היקפים מעבר ברירת המחדל שברצונך הבקשה מספקת אימות.

    provider_data.scopes.push_back("email");
    provider_data.scopes.push_back("name");
    
  3. אופציונלי: אם אתה רוצה להציג הכניסה של אפל מסך בשפה שאינה אנגלית, להגדיר את locale הפרמטר. עיין היכנס עם docs האפל עבור האזורים הנתמכים.

    // 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 שלהם לנתונים אחרים.

    לדוגמה, כדי לקשר חשבון פייסבוק לחשבון Firebase הנוכחי, השתמש באסימון הגישה שקיבלת מהכניסה למשתמש לפייסבוק:

    // 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, אפל אינה מספקת כתובת אתר של תמונה.

כמו כן, כאשר המשתמש בוחר לא לשתף הדוא"ל שלהם עם האפליקציה, הוראות אפלות כתוב דואר אלקטרונית ייחודית עבור משתמש זה (מהצורה xyz@privaterelay.appleid.com ), אשר בה מניות עם האפליקציה שלך. אם הגדרת את שירות ממסר הדוא"ל הפרטי, אפל מעבירה דוא"ל שנשלח לכתובת האנונימית לכתובת הדוא"ל האמיתית של המשתמש.

אפל רק פרטי משתמש מניות כגון שם תצוגה עם אפליקציות לראשונה שמשתמש נכנס. בדרך כלל, בחנויות Firebase את השם לתצוגה בפעם הראשונה שמשתמש נכנס עם אפל, שבו אתה יכול לקבל עם getCurrentUser().getDisplayName() . עם זאת, אם בעבר השתמשת באפל כדי להיכנס למשתמש לאפליקציה מבלי להשתמש ב- Firebase, אפל לא תספק ל- Firebase את שם התצוגה של המשתמש.

הצעדים הבאים

לאחר שמשתמש נכנס בפעם הראשונה, נוצר חשבון משתמש חדש ומקושר לאישורי האישור - כלומר לשם המשתמש והסיסמה, מספר הטלפון או פרטי ספק האימות - המשתמש נכנס איתו. חשבון חדש זה מאוחסן כחלק מפרויקט Firebase שלך, וניתן להשתמש בו כדי לזהות משתמש בכל אפליקציה בפרויקט שלך, ללא קשר לאופן בו המשתמש נכנס.

באפליקציות שלך תוכל לקבל את פרטי הפרופיל הבסיסי של המשתמש מאובייקט המשתמש firebase :: auth ::. ראו ניהול משתמשים .

במסד הנתונים שלך בזמן אמת של Firebase ובכללי האבטחה של אחסון ענן, אתה יכול לקבל את מזהה המשתמש הייחודי של המשתמש המחובר ממשתנה האימות, ולהשתמש בו כדי לשלוט לאילו נתונים המשתמש יכול לגשת.