אימות באמצעות Yahoo בפלטפורמות של Apple

אתם יכולים לאפשר למשתמשים לבצע אימות ב-Firebase באמצעות ספקי OAuth כמו Yahoo. לשם כך, משלבים את OAuth Login הגנרי באפליקציה באמצעות Firebase SDK כדי לבצע את תהליך הכניסה מקצה לקצה.

לפני שמתחילים

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

  1. מוסיפים את Firebase לפרויקט ב-Apple.
  2. במסוף Firebase, פותחים את הקטע Auth.
  3. בכרטיסייה שיטת כניסה, מפעילים את הספק Yahoo.
  4. מוסיפים את Client ID ואת Client Secret ממסוף המפתחים של הספק הזה אל תצורת ספק:
    1. כדי לרשום לקוח OAuth של Yahoo, פועלים לפי ההוראות במסמכי העזרה למפתחים של Yahoo בנושא רישום אפליקציית אינטרנט ב-Yahoo.

      חשוב לבחור את שתי ההרשאות של OpenID Connect API: profile ו-email.

    2. כשרושמים אפליקציות אצל הספקים האלה, חשוב לרשום את הדומיין *.firebaseapp.com של הפרויקט כדומיין ההפניה האוטומטית של אפליקציה.
  5. לוחצים על שמירה.

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

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

  1. מוסיפים סכימות של כתובות URL מותאמות אישית לפרויקט Xcode:

    1. פותחים את הגדרות הפרויקט: לוחצים לחיצה כפולה על שם הפרויקט תצוגת עץ שמאלית בוחרים את האפליקציה בקטע TARGETS, ואז לוחצים על הכרטיסייה Info ומרחיבים את הקטע URL Types.
    2. לוחצים על הלחצן + ומוסיפים את מזהה האפליקציה המקודד ככתובת URL. scheme. ניתן למצוא את מזהה האפליקציה המקודד כללי דף הגדרות במסוף Firebase, בקטע של iOS אפליקציה. משאירים את שאר השדות ריקים.

      בסיום התהליך, ההגדרה אמורה להיראות בערך כך הבא (אבל עם הערכים הספציפיים לאפליקציה שלך):

      צילום מסך של ממשק ההגדרה של סכימה של כתובת URL מותאמת אישית ב-Xcode

  2. יוצרים מופע של OAuthProvider באמצעות מזהה הספק yahoo.com.

    var provider = OAuthProvider(providerID: "yahoo.com")
        
    FIROAuthProvider *provider = [FIROAuthProvider providerWithProviderID:@"yahoo.com"];
        
  3. אופציונלי: מציינים פרמטרים מותאמים אישית נוספים של OAuth שרוצים להגדיר שליחה עם בקשת ה-OAuth.

    provider.customParameters = [
    "prompt": "login",
    "language": "fr"
    ]
        
    [provider setCustomParameters:@{@"prompt": @"login", @"language": @"fr"}];
        

    הפרמטרים שבהם Yahoo תומכת מפורטים במסמכי התיעוד של Yahoo OAuth. שימו לב שאי אפשר להעביר פרמטרים שנדרשים ל-Firebase עם setCustomParameters הפרמטרים האלה הם client_id, redirect_uri, response_type, scope ו-state.

  4. אופציונלי: אפשר לציין היקפי הרשאות OAuth 2.0 נוספים, מעבר ל-profile וכן email שברצונך לבקש מספק האימות. אם נדרשת גישה לנתוני משתמשים פרטיים מ-Yahoo APIs, תצטרכו לבקש הרשאות ל-Yahoo APIs בקטע הרשאות API Yahoo Developer Console. היקפי ה-OAuth המבוקשים חייבים להיות זהים להיקפים שהוגדרו מראש בהרשאות ה-API של האפליקציה. לדוגמה, אם בוחרים בקריאה/כתיבה הם מתבקשים לגשת לאנשי הקשר של המשתמשים, והם מוגדרים מראש ב-API של האפליקציה הרשאות, צריך להעביר את sdct-w במקום היקף הרשאות ה-OAuth לקריאה בלבד sdct-r. אחרת, התהליך ייכשל ותוצג שגיאה למשתמש קצה.

    // Request access to Yahoo Mail API.
    // Request read/write access to user contacts.
    // This must be preconfigured in the app's API permissions.
    provider.scopes = ["mail-r", "sdct-w"]
        
    // Request access to Yahoo Mail API.
    // Request read/write access to user contacts.
    // This must be preconfigured in the app's API permissions.
    [provider setScopes:@[@"mail-r", @"sdct-w"]];
        

    למידע נוסף, אפשר לעיין במסמכי התיעוד בנושא היקפי הרשאה ב-Yahoo.

  5. אופציונלי: אם רוצים להתאים אישית את האופן שבו האפליקציה מציגה את SFSafariViewController או את UIWebView כשהיא מציגה את reCAPTCHA למשתמש, יוצרים כיתה מותאמת אישית שתואמת לפרוטוקול AuthUIDelegate ומעבירים אותה ל-credentialWithUIDelegate.

  6. אימות באמצעות 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.
      // Yahoo OAuth access token can also be retrieved by:
      // (authResult.credential as? OAuthCredential)?.accessToken
      // Yahoo OAuth ID token can be retrieved by calling:
      // (authResult.credential as? 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.
      // Yahoo OAuth access token can also be retrieved by:
      // ((FIROAuthCredential *)authResult.credential).accessToken
      // Yahoo OAuth ID token can be retrieved by calling:
      // ((FIROAuthCredential *)authResult.credential).idToken
    }];
    }
    }];
        

    באמצעות אסימון הגישה של OAuth, אפשר לקרוא ל- Yahoo API

    לדוגמה, כדי לקבל פרטי פרופיל בסיסיים, אפשר לקרוא ל-API ל-REST, העברת אסימון הגישה בכותרת Authorization:

    https://social.yahooapis.com/v1/user/YAHOO_USER_UID/profile?format=json

    כאשר YAHOO_USER_UID הוא מזהה המשתמש ב-Yahoo שאפשר לאחזר מ: השדה Auth.auth.currentUser.providerData[0].uid או מתוך authResult.additionalUserInfo.profile.

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

    Auth().currentUser.link(withCredential: credential) { authResult, error in
    if error != nil {
    // Handle error.
    }
    // Yahoo credential is linked to the current user.
    // IdP data available in authResult.additionalUserInfo.profile.
    // Yahoo OAuth access token can also be retrieved by:
    // (authResult.credential as? OAuthCredential)?.accessToken
    // Yahoo 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.
    }
    // Yahoo credential is linked to the current user.
    // IdP data available in authResult.additionalUserInfo.profile.
    // Yahoo OAuth access token is can also be retrieved by:
    // ((FIROAuthCredential *)authResult.credential).accessToken
    // Yahoo OAuth ID token can be retrieved by calling:
    // ((FIROAuthCredential *)authResult.credential).idToken
    }];
        
  8. אפשר להשתמש באותו דפוס עם reauthenticateWithPopup/reauthenticateWithRedirect, כדי לאחזר פרטי כניסה עדכניים לפעולות רגישות שדורשות התחברות מהזמן האחרון.

    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
    // Yahoo 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
    // Yahoo OAuth ID token can be retrieved by calling:
    // ((FIROAuthCredential *)authResult.credential).idToken
    }];
        

אם הפעלתם את ההגדרה חשבון אחד לכל כתובת אימייל במסוף Firebase, כשמשתמש מנסה להיכנס לחשבון אצל ספק (למשל Yahoo) באמצעות כתובת אימייל שכבר קיים לספק אחר של משתמש Firebase (כמו Google), השגיאה זריקת FIRAuthErrorCodeAccountExistsWithDifferentCredential ביחד עם ערך זמני אובייקט FIRAuthCredential (פרטי כניסה ל-Yahoo). כדי להשלים את הכניסה אל הספק הקיים צריך להיכנס קודם לספק הקיים (Google) ואז לקשר FIRAuthCredential לשעבר (פרטי כניסה ל-Yahoo). זה ייראה כך:

  // 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;
        }
      }];
    }
  }];
  

בניגוד לספקי OAuth אחרים שנתמכים על ידי Firebase, כמו Google, Facebook, וב-Twitter, שבהם אפשר להיכנס ישירות לחשבון באמצעות אסימון גישה ל-OAuth שמבוססים על פרטי כניסה, אימות Firebase לא תומך באותה יכולת עבור כמו Yahoo בגלל חוסר היכולת של Firebase שרת אימות לאימות הקהל של אסימוני הגישה של Yahoo OAuth. זוהי דרישת אבטחה קריטית, והיא עלולה לחשוף אפליקציות ואתרים למתקפות של שחזור, שבהן אפשר להשתמש באסימון גישה של Yahoo OAuth שנוצר לפרויקט אחד (תוקף) כדי להיכנס לפרויקט אחר (קורבן). במקום זאת, Firebase Auth מאפשר לטפל בכל תהליך OAuth ובהחלפת קוד ההרשאה באמצעות מזהה הלקוח והסוד של OAuth שהוגדרו במסוף Firebase. מאחר שניתן להשתמש רק בקוד ההרשאה יחד עם מזהה/סוד לקוח ספציפי, קוד הרשאה שהתקבלו עבור פרויקט אחד, לא יכולות לשמש בפרויקט אחר.

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

השלבים הבאים

אחרי שמשתמש נכנס בפעם הראשונה, נוצר חשבון משתמש חדש שמקושרות לפרטי הכניסה - כלומר שם המשתמש והסיסמה, מספר הטלפון מספר, או פרטים של ספק אימות – המשתמש נכנס באמצעותו. החדש הזה מאוחסנים כחלק מפרויקט 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;
}

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

Firebase Authentication lets you add an end-to-end identity solution to your app for easy user authentication, sign-in, and onboarding in just a few lines of code.

עדכון אחרון: Feb 28, 2025

Firebase Authentication lets you add an end-to-end identity solution to your app for easy user authentication, sign-in, and onboarding in just a few lines of code.

עדכון אחרון: Feb 28, 2025

Firebase Authentication lets you add an end-to-end identity solution to your app for easy user authentication, sign-in, and onboarding in just a few lines of code.

עדכון אחרון: Feb 28, 2025