ตรวจสอบสิทธิ์ด้วย Firebase โดยใช้บัญชีด้วยรหัสผ่านโดยใช้ C++

คุณสามารถใช้ Firebase Authentication เพื่ออนุญาตให้ผู้ใช้ตรวจสอบสิทธิ์กับ Firebase โดยใช้อีเมลและรหัสผ่าน รวมถึงจัดการบัญชีที่อิงตามรหัสผ่านของแอป

ก่อนเริ่มต้น

  1. เพิ่ม Firebase ไปยังโปรเจ็กต์ C++
  2. หากยังไม่ได้เชื่อมต่อแอปกับโปรเจ็กต์ Firebase ให้เชื่อมต่อจากคอนโซล Firebase
  3. เปิดใช้การลงชื่อเข้าใช้ด้วยอีเมล/รหัสผ่าน
    1. ในคอนโซล Firebase ให้เปิดส่วน Auth
    2. ในแท็บวิธีการลงชื่อเข้าใช้ ให้เปิดใช้วิธีการลงชื่อเข้าใช้อีเมล/รหัสผ่าน แล้วคลิกบันทึก

เข้าถึงชั้นเรียน firebase::auth::Auth

คลาส Auth เป็นเกตเวย์สําหรับการเรียก API ทั้งหมด
  1. เพิ่มไฟล์ส่วนหัวของ Auth และ 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 มีการแมปแบบ 1:1 ระหว่าง App กับ Auth
    firebase::auth::Auth* auth = firebase::auth::Auth::GetAuth(app);

สร้างบัญชีที่ใช้รหัสผ่าน

หากต้องการสร้างบัญชีผู้ใช้ใหม่ด้วยรหัสผ่าน ให้ทำตามขั้นตอนต่อไปนี้ในรหัสลงชื่อเข้าใช้ของแอป

  1. เมื่อผู้ใช้ใหม่ลงชื่อสมัครใช้โดยใช้แบบฟอร์มลงชื่อสมัครใช้ของแอป ให้ทำตามขั้นตอน การตรวจสอบบัญชีใหม่ให้เสร็จสมบูรณ์ที่แอปของคุณต้องการ เช่น ยืนยันว่า รหัสผ่านของบัญชีใหม่พิมพ์อย่างถูกต้องและตรงตามข้อกำหนด ความซับซ้อนของคุณ
  2. สร้างบัญชีใหม่โดยส่งอีเมลและรหัสผ่านของผู้ใช้ใหม่ให้กับ Auth::CreateUserWithEmailAndPassword
    firebase::Future<firebase::auth::AuthResult> result =
        auth->CreateUserWithEmailAndPassword(email, password);
  3. หากโปรแกรมมีลูปการอัปเดตที่ทำงานเป็นประจำ (เช่น 30 หรือ 60 ครั้งต่อวินาที) คุณสามารถตรวจสอบผลลัพธ์ได้ 1 ครั้งต่อการอัปเดตด้วย Auth::CreateUserWithEmailAndPasswordLastResult ดังนี้
    firebase::Future<firebase::auth::AuthResult> result =
        auth->CreateUserWithEmailAndPasswordLastResult();
    if (result.status() == firebase::kFutureStatusComplete) {
      if (result.error() == firebase::auth::kAuthErrorNone) {
        const firebase::auth::AuthResult auth_result = *result.result();
        printf("Create user succeeded for email %s\n",
               auth_result.user.email().c_str());
      } else {
        printf("Created user failed with error '%s'\n", result.error_message());
      }
    }
    หรือหากโปรแกรมของคุณทำงานตามเหตุการณ์ คุณอาจต้องลงทะเบียนการเรียกกลับในอนาคต

ลงชื่อเข้าใช้ผู้ใช้ด้วยอีเมลและรหัสผ่าน

ขั้นตอนในการลงชื่อเข้าใช้ให้ผู้ใช้ด้วยรหัสผ่านคล้ายกับขั้นตอนในการสร้างบัญชีใหม่ ในฟังก์ชันการลงชื่อเข้าใช้ของแอป ให้ทำดังนี้

  1. เมื่อผู้ใช้ลงชื่อเข้าใช้แอป ให้ส่งอีเมลและรหัสผ่านของผู้ใช้ไปยัง firebase::auth::Auth::SignInWithEmailAndPassword:
    firebase::Future<firebase::auth::AuthResult> result =
        auth->SignInWithEmailAndPassword(email, password);
  2. หากโปรแกรมมีลูปการอัปเดตที่ทำงานเป็นประจำ (เช่น 30 หรือ 60 ครั้งต่อวินาที) คุณสามารถตรวจสอบผลลัพธ์ได้ 1 ครั้งต่อการอัปเดตด้วย Auth::SignInWithEmailAndPasswordLastResult ดังนี้
    firebase::Future<firebase::auth::AuthResult> result =
        auth->SignInWithEmailAndPasswordLastResult();
    if (result.status() == firebase::kFutureStatusComplete) {
      if (result.error() == firebase::auth::kAuthErrorNone) {
        const firebase::auth::AuthResult auth_result = *result.result();
        printf("Sign in succeeded for email %s\n",
               auth_result.user.email().c_str());
      } else {
        printf("Sign in failed with error '%s'\n", result.error_message());
      }
    }
    หรือหากโปรแกรมของคุณมีการจัดกิจกรรม คุณสามารถ ลงทะเบียนการติดต่อกลับใน อนาคต

ลงทะเบียนการเรียกกลับใน Future

บางโปรแกรมมีฟังก์ชัน Update ที่มีการเรียกใช้ 30 หรือ 60 ครั้งต่อวินาที ตัวอย่างเช่น เกมจำนวนมากใช้รูปแบบนี้ โปรแกรมเหล่านี้สามารถเรียกใช้ฟังก์ชัน LastResult เพื่อสำรวจการเรียกแบบไม่พร้อมกัน อย่างไรก็ตาม หากโปรแกรมของคุณทำงานตามเหตุการณ์ คุณอาจต้องลงทะเบียนฟังก์ชันการเรียกกลับ ระบบจะเรียกใช้ฟังก์ชัน Callback เมื่อ Future เสร็จสมบูรณ์
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 อาจเป็น lambda ก็ได้หากต้องการ
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 Authentication รองรับข้อกำหนดด้านรหัสผ่านต่อไปนี้

  • ต้องมีอักขระตัวพิมพ์เล็ก

  • ต้องมีอักขระตัวพิมพ์ใหญ่

  • ต้องมีอักขระที่เป็นตัวเลข

  • ต้องมีอักขระที่ไม่ใช่ตัวอักษรและตัวเลขคละกัน

    อักขระต่อไปนี้เป็นไปตามข้อกำหนดของอักขระที่ไม่ใช่ตัวอักษรและตัวเลข ^ $ * . [ ] { } ( ) ? " ! @ # % & / \ , > < ' : ; | _ ~

  • ความยาวขั้นต่ำของรหัสผ่าน (ช่วงตั้งแต่ 6 ถึง 30 อักขระ ค่าเริ่มต้นคือ 6)

  • ความยาวสูงสุดของรหัสผ่าน (สูงสุด 4096 อักขระ)

คุณเปิดใช้การบังคับใช้นโยบายรหัสผ่านได้ 2 โหมด ดังนี้

  • ต้อง: การพยายามลงชื่อสมัครใช้จะล้มเหลวจนกว่าผู้ใช้จะอัปเดตเป็นรหัสผ่านที่เป็นไปตามนโยบายของคุณ

  • แจ้งเตือน: ผู้ใช้ได้รับอนุญาตให้ลงชื่อสมัครใช้ด้วยรหัสผ่านที่ไม่เป็นไปตามข้อกำหนด เมื่อใช้โหมดนี้ คุณควรตรวจสอบว่ารหัสผ่านของผู้ใช้เป็นไปตามนโยบายฝั่งไคลเอ็นต์หรือไม่ และแจ้งให้ผู้ใช้อัปเดตรหัสผ่านหากไม่เป็นไปตามนโยบาย

ผู้ใช้ใหม่จะต้องเลือกรหัสผ่านที่เป็นไปตามนโยบายของคุณเสมอ

หากคุณมีผู้ใช้ที่ใช้งานอยู่ ขอแนะนำว่าอย่าเปิดใช้การบังคับอัปเกรดเมื่อลงชื่อเข้าใช้ เว้นแต่คุณจะมีเจตนาบล็อกการเข้าถึงผู้ใช้ที่มีรหัสผ่านไม่เป็นไปตามนโยบายของคุณ แต่ให้ใช้โหมดการแจ้งเตือนแทน ซึ่งจะอนุญาตให้ผู้ใช้ลงชื่อเข้าใช้ด้วยรหัสผ่านปัจจุบันและแจ้งให้ผู้ใช้ทราบถึงข้อกำหนดที่รหัสผ่านไม่เป็นไปตาม

แนะนำ: เปิดใช้การป้องกันการนับอีเมล

เมธอด Firebase Authentication บางรายการที่ใช้อีเมลเป็นพารามิเตอร์จะแสดงข้อผิดพลาดที่เฉพาะเจาะจงหากอีเมลไม่ได้ลงทะเบียนเมื่อต้องลงทะเบียน (เช่น เมื่อลงชื่อเข้าใช้ด้วยอีเมลและรหัสผ่าน) หรือลงทะเบียนเมื่อต้องไม่ใช้งาน (เช่น เมื่อเปลี่ยนอีเมลของผู้ใช้) แม้วิธีนี้จะมีประโยชน์ในการแนะนำวิธีแก้ปัญหาบางอย่างแก่ผู้ใช้ แต่ผู้ไม่ประสงค์ดีก็อาจละเมิดเพื่อค้นหาที่อยู่อีเมลที่ผู้ใช้ของคุณลงทะเบียนไว้

เพื่อลดความเสี่ยงนี้ เราขอแนะนำให้คุณเปิดใช้การป้องกันการแจงนับอีเมลสำหรับโปรเจ็กต์ของคุณโดยใช้เครื่องมือ gcloud ของ Google Cloud โปรดทราบว่าการเปิดใช้ฟีเจอร์นี้จะเปลี่ยนลักษณะการรายงานข้อผิดพลาดของ Firebase Authentication โปรดตรวจสอบว่าแอปของคุณไม่ได้ใช้ข้อผิดพลาดที่เฉพาะเจาะจงมากขึ้น

ขั้นตอนถัดไป

หลังจากผู้ใช้ลงชื่อเข้าใช้เป็นครั้งแรก ระบบจะสร้างบัญชีผู้ใช้ใหม่และลิงก์กับข้อมูลเข้าสู่ระบบ ซึ่งก็คือชื่อผู้ใช้และรหัสผ่าน หมายเลขโทรศัพท์ หรือข้อมูลของผู้ให้บริการการตรวจสอบสิทธิ์ ซึ่งผู้ใช้ที่ลงชื่อเข้าใช้ด้วย ระบบจะจัดเก็บบัญชีใหม่นี้เป็นส่วนหนึ่งของโปรเจ็กต์ 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();