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

כדי לאפשר למשתמשים לבצע אימות ב-Firebase באמצעות חשבונות GitHub שלהם, אפשר לשלב את אימות GitHub באפליקציה.

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

  1. מוסיפים את Firebase לפרויקט C++.
  2. במסוף Firebase, פותחים את הקטע אימות.
  3. בכרטיסייה Sign in method, מפעילים את הספק GitHub.
  4. מוסיפים את Client ID ואת Client Secret ממסוף המפתחים של הספק הזה אל תצורת ספק:
    1. רישום האפליקציה בתור אפליקציית מפתחים ב-GitHub ולקבל את מזהה הלקוח של OAuth 2.0 של האפליקציה ו-Client Secret.
    2. מוודאים שכתובת ה-URI להפניה אוטומטית של OAuth ב-Firebase (למשל my-app-12345.firebaseapp.com/__/auth/handler) מוגדרת ככתובת ה-URL להודעת החזרה (callback) של ההרשאה בדף ההגדרות של האפליקציה בתצורה של אפליקציית GitHub.
  5. לוחצים על שמירה.

גישה לכיתה 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

  1. צריך לפעול לפי ההוראות של ב-Android ו-iOS+ כדי לקבל אסימון למשתמש שמחובר ב-GitHub.
  2. אחרי שמשתמש נכנס, מחליפים את האסימון ב פרטי כניסה ל-Firebase ואימות מול Firebase באמצעות Firebase פרטי כניסה:
    firebase::auth::Credential credential =
        firebase::auth::GitHubAuthProvider::GetCredential(token);
    firebase::Future<firebase::auth::AuthResult> result =
        auth->SignInAndRetrieveDataWithCredential(credential);
    
  3. אם לתוכנית יש לולאת עדכון שרצה באופן קבוע (למשל ב-30 או ב-60) פעמים בשנייה), אפשר לבדוק את התוצאות פעם אחת בכל עדכון Auth::SignInAndRetrieveDataWithCredentialLastResult:
    firebase::Future<firebase::auth::AuthResult> result =
        auth->SignInAndRetrieveDataWithCredentialLastResult();
    if (result.status() == firebase::kFutureStatusComplete) {
      if (result.error() == firebase::auth::kAuthErrorNone) {
        firebase::auth::AuthResult auth_result = *result.result();
        printf("Sign in succeeded for `%s`\n",
               auth_result.user.display_name().c_str());
      } else {
        printf("Sign in failed with error '%s'\n", result.error_message());
      }
    }
    
    לחלופין, אם התוכנית מבוססת על אירועים, ייתכן שתעדיפו לרשום קריאה חוזרת העתידי.

רישום קריאה חוזרת (callback) בעתיד

בתוכנות מסוימות יש פונקציות Update שנקראות 30 או 60 פעמים בשנייה. לדוגמה, יש הרבה משחקים שמבוססים על המודל הזה. התוכניות האלה יכולות לקרוא לLastResult לדגום קריאות אסינכרוניות. עם זאת, אם התוכנית שלכם מבוססת על אירועים, יכול להיות שתעדיפו לרשום פונקציות קריאה חוזרת (callback). מתבצעת קריאה לפונקציית קריאה חוזרת (callback) לאחר השלמת העתיד.
void OnCreateCallback(const firebase::Future<firebase::auth::User*>& result,
                      void* user_data) {
  // The callback is called when the Future enters the `complete` state.
  assert(result.status() == firebase::kFutureStatusComplete);

  // Use `user_data` to pass-in program context, if you like.
  MyProgramContext* program_context = static_cast<MyProgramContext*>(user_data);

  // Important to handle both success and failure situations.
  if (result.error() == firebase::auth::kAuthErrorNone) {
    firebase::auth::User* user = *result.result();
    printf("Create user succeeded for email %s\n", user->email().c_str());

    // Perform other actions on User, if you like.
    firebase::auth::User::UserProfile profile;
    profile.display_name = program_context->display_name;
    user->UpdateUserProfile(profile);

  } else {
    printf("Created user failed with error '%s'\n", result.error_message());
  }
}

void CreateUser(firebase::auth::Auth* auth) {
  // Callbacks work the same for any firebase::Future.
  firebase::Future<firebase::auth::AuthResult> result =
      auth->CreateUserWithEmailAndPasswordLastResult();

  // `&my_program_context` is passed verbatim to OnCreateCallback().
  result.OnCompletion(OnCreateCallback, &my_program_context);
}
אם רוצים, אפשר להשתמש גם בפונקציית למדה כפונקציית ה-callback.
void CreateUserUsingLambda(firebase::auth::Auth* auth) {
  // Callbacks work the same for any firebase::Future.
  firebase::Future<firebase::auth::AuthResult> result =
      auth->CreateUserWithEmailAndPasswordLastResult();

  // The lambda has the same signature as the callback function.
  result.OnCompletion(
      [](const firebase::Future<firebase::auth::User*>& result,
         void* user_data) {
        // `user_data` is the same as &my_program_context, below.
        // Note that we can't capture this value in the [] because std::function
        // is not supported by our minimum compiler spec (which is pre C++11).
        MyProgramContext* program_context =
            static_cast<MyProgramContext*>(user_data);

        // Process create user result...
        (void)program_context;
      },
      &my_program_context);
}

השלבים הבאים

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

  • באפליקציות שלכם, תוכלו לקבל את פרטי הפרופיל הבסיסיים של המשתמש דרך אובייקט firebase::auth::User:

    firebase::auth::User user = auth->current_user();
    if (user.is_valid()) {
      std::string name = user.display_name();
      std::string email = user.email();
      std::string photo_url = user.photo_url();
      // The user's ID, unique to the Firebase project.
      // Do NOT use this value to authenticate with your backend server,
      // if you have one. Use firebase::auth::User::Token() instead.
      std::string uid = user.uid();
    }
    
  • בתוך Firebase Realtime Database ו-Cloud Storage כללי אבטחה – מקבלים את מזהה המשתמש הייחודי של המשתמש המחובר מהמשתנה auth, ולהשתמש בהם כדי לקבוע לאילו נתונים המשתמש יוכל לגשת.

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

כדי לנתק משתמש מהחשבון, יש להתקשר אל SignOut():

auth->SignOut();