ตรวจสอบสิทธิ์โดยใช้ OpenID Connect บนแพลตฟอร์ม Apple

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

ก่อนที่คุณจะเริ่มต้น

ในการลงชื่อเข้าใช้ผู้ใช้โดยใช้ผู้ให้บริการ OIDC คุณต้องรวบรวมข้อมูลบางอย่างจากผู้ให้บริการก่อน:

  • รหัสลูกค้า : สตริงเฉพาะของผู้ให้บริการที่ระบุแอปของคุณ ผู้ให้บริการของคุณอาจกำหนดรหัสลูกค้าที่แตกต่างกันสำหรับแต่ละแพลตฟอร์มที่คุณสนับสนุน นี่เป็นหนึ่งในค่าของการ aud สิทธิ์ในโทเค็น ID ที่ออกโดยผู้ให้บริการของคุณ

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

  • ผู้ออก : สตริงที่ระบุผู้ให้บริการของคุณ ค่านี้ต้องเป็น URL ที่เมื่อต่อท้ายด้วย /.well-known/openid-configuration เป็นตำแหน่งของเอกสารการค้นพบ OIDC ของผู้ให้บริการ ตัวอย่างเช่น หากผู้ออกคือ https://auth.example.com เอกสารการค้นพบจะต้องมีอยู่ที่ https://auth.example.com/.well-known/openid-configuration

หลังจากที่คุณมีข้อมูลข้างต้นแล้ว ให้เปิดใช้งาน OpenID Connect เป็นผู้ให้บริการลงชื่อเข้าใช้สำหรับโครงการ Firebase ของคุณ:

  1. เพิ่ม Firebase ในโครงการ iOS ของคุณ

  2. หากคุณยังไม่ได้อัปเกรดเป็น Firebase Authentication ด้วย Identity Platform ให้ดำเนินการดังกล่าว การรับรองความถูกต้องของ OpenID Connect ใช้ได้เฉพาะในโปรเจ็กต์ที่อัปเกรดแล้วเท่านั้น

  3. ในหน้า ผู้ให้บริการลงชื่อเข้าใช้ ของคอนโซล Firebase ให้คลิก เพิ่มผู้ให้บริการใหม่ จากนั้นคลิก OpenID Connect

  4. เลือกว่าคุณจะใช้ โฟลว์รหัสการให้สิทธิ์ หรือ โฟลว์การให้สิทธิ์โดยปริยาย

    คุณควรใช้โฟลว์ของโค้ดเสมอหากผู้ให้บริการของคุณสนับสนุน โฟลว์โดยปริยายมีความปลอดภัยน้อยกว่าและไม่แนะนำให้ใช้อย่างยิ่ง

  5. ตั้งชื่อให้กับผู้ให้บริการรายนี้ สังเกตรหัสผู้ให้บริการที่สร้างขึ้น: คล้ายกับ oidc.example-provider คุณต้องใช้รหัสนี้เมื่อเพิ่มรหัสลงชื่อเข้าใช้ในแอป

  6. ระบุรหัสไคลเอนต์และความลับไคลเอ็นต์ของคุณ และสตริงผู้ออกของผู้ให้บริการของคุณ ค่าเหล่านี้ต้องตรงกับค่าที่ผู้ให้บริการกำหนดให้กับคุณทุกประการ

  7. บันทึกการเปลี่ยนแปลงของคุณ

จัดการขั้นตอนการลงชื่อเข้าใช้ด้วย Firebase SDK

วิธีที่ง่ายที่สุดในการตรวจสอบสิทธิ์ผู้ใช้ด้วย Firebase โดยใช้ผู้ให้บริการ OIDC คือจัดการขั้นตอนการลงชื่อเข้าใช้ทั้งหมดด้วย Firebase SDK

หากต้องการจัดการขั้นตอนการลงชื่อเข้าใช้ด้วย Firebase Apple platforms SDK ให้ทำตามขั้นตอนเหล่านี้:

  1. เพิ่มรูปแบบ URL ที่กำหนดเองในโครงการ Xcode ของคุณ:

    1. เปิดการกำหนดค่าโครงการของคุณ: ดับเบิลคลิกที่ชื่อโครงการในมุมมองแบบต้นไม้ด้านซ้าย เลือกแอปของคุณจากส่วน เป้าหมาย จากนั้นเลือกแท็บ ข้อมูล และขยายส่วน ประเภท URL
    2. คลิกปุ่ม + และเพิ่ม ID แอปที่เข้ารหัสเป็นรูปแบบ URL คุณสามารถค้นหา ID แอปที่เข้ารหัสของคุณได้ในหน้า การตั้งค่าทั่วไป ของคอนโซล Firebase ในส่วนสำหรับแอป iOS ของคุณ เว้นช่องอื่นๆ ว่างไว้

      เมื่อเสร็จแล้ว การกำหนดค่าของคุณควรมีลักษณะดังนี้ (แต่มีค่าเฉพาะแอปพลิเคชันของคุณ):

      ภาพหน้าจอของอินเทอร์เฟซการตั้งค่ารูปแบบ URL ที่กำหนดเองของ Xcode
  2. สร้างอินสแตนซ์ของ OAuthProvider โดยใช้ ID ผู้ให้บริการที่คุณได้รับในคอนโซล Firebase

    สวิฟต์

    var provider = OAuthProvider(providerID: "oidc.example-provider")
    

    วัตถุประสงค์-C

    FIROAuthProvider *provider = [FIROAuthProvider providerWithProviderID:@"oidc.example-provider"];
    
  3. ทางเลือก : ระบุพารามิเตอร์ OAuth ที่กำหนดเองเพิ่มเติมที่คุณต้องการส่งพร้อมกับคำขอ OAuth

    สวิฟต์

    provider.customParameters = [
      "login_hint": "user@example.com"
    ]
    

    วัตถุประสงค์-C

    [provider setCustomParameters:@{@"login_hint": @"user@example.com"}];
    

    ตรวจสอบกับผู้ให้บริการของคุณสำหรับพารามิเตอร์ที่รองรับ โปรดทราบว่าคุณไม่สามารถส่งพารามิเตอร์ที่กำหนดโดย Firebase กับ setCustomParameters พารามิเตอร์เหล่านี้คือ client_id , response_type , redirect_uri , state , scope และ response_mode

  4. ทางเลือก : ระบุขอบเขต OAuth 2.0 เพิ่มเติมนอกเหนือจากโปรไฟล์พื้นฐานที่คุณต้องการร้องขอจากผู้ให้บริการตรวจสอบสิทธิ์

    สวิฟต์

    provider.scopes = ["mail.read", "calendars.read"]
    

    วัตถุประสงค์-C

    [provider setScopes:@[@"mail.read", @"calendars.read"]];
    

    ตรวจสอบกับผู้ให้บริการของคุณสำหรับขอบเขตที่รองรับ

  5. ทางเลือก : หากคุณต้องการปรับแต่งวิธีที่แอปของคุณนำเสนอ SFSafariViewController หรือ UIWebView เมื่อแสดง reCAPTCHA แก่ผู้ใช้ ให้สร้างคลาสแบบกำหนดเองที่สอดคล้องกับโปรโตคอล AuthUIDelegate

  6. รับรองความถูกต้องกับ Firebase โดยใช้วัตถุผู้ให้บริการ OAuth

    สวิฟต์

    // If you created a custom class that conforms to AuthUIDelegate,
    // pass it instead of nil:
    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.
          // OAuth access token can also be retrieved:
          // (authResult.credential as? OAuthCredential)?.accessToken
          // OAuth ID token can also be retrieved:
          // (authResult.credential as? OAuthCredential)?.idToken
        }
      }
    }
    

    วัตถุประสงค์-C

    // If you created a custom class that conforms to AuthUIDelegate,
    // pass it instead of nil:
    [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.
          // OAuth access token can also be retrieved:
          // ((FIROAuthCredential *)authResult.credential).accessToken
          // OAuth ID token can also be retrieved:
          // ((FIROAuthCredential *)authResult.credential).idToken
        }];
      }
    }];
    
  7. แม้ว่าตัวอย่างข้างต้นจะมุ่งเน้นไปที่ขั้นตอนการลงชื่อเข้าใช้ คุณยังมีความสามารถในการเชื่อมโยงผู้ให้บริการ OIDC กับผู้ใช้ที่มีอยู่โดยใช้ linkWithCredential ตัวอย่างเช่น คุณสามารถเชื่อมโยงผู้ให้บริการหลายรายกับผู้ใช้รายเดียวกัน โดยอนุญาตให้พวกเขาลงชื่อเข้าใช้ด้วยผู้ให้บริการรายใดรายหนึ่ง

    สวิฟต์

    Auth().currentUser.link(withCredential: credential) { authResult, error in
      if error != nil {
        // Handle error.
      }
      // OIDC credential is linked to the current user.
      // IdP data available in authResult.additionalUserInfo.profile.
      // OAuth access token can also be retrieved:
      // (authResult.credential as? OAuthCredential)?.accessToken
      // OAuth ID token can also be retrieved:
      // (authResult.credential as? OAuthCredential)?.idToken
    }
    

    วัตถุประสงค์-C

    [[FIRAuth auth].currentUser
        linkWithCredential:credential
                completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
      if (error) {
        // Handle error.
      }
      // OIDC credential is linked to the current user.
      // IdP data available in authResult.additionalUserInfo.profile.
      // OAuth access token can also be retrieved:
      // ((FIROAuthCredential *)authResult.credential).accessToken
      // OAuth ID token can also be retrieved:
      // ((FIROAuthCredential *)authResult.credential).idToken
    }];
    
  8. สามารถใช้รูปแบบเดียวกันนี้กับ reauthenticateWithCredential ซึ่งสามารถใช้เพื่อดึงข้อมูลรับรองใหม่สำหรับการดำเนินการที่ละเอียดอ่อนซึ่งต้องมีการเข้าสู่ระบบล่าสุด

    สวิฟต์

    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 can also be retrieved:
      // (authResult.credential as? OAuthCredential)?.accessToken
      // OAuth ID token can also be retrieved:
      // (authResult.credential as? OAuthCredential)?.idToken
    }
    

    วัตถุประสงค์-C

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

จัดการขั้นตอนการลงชื่อเข้าใช้ด้วยตนเอง

หากคุณใช้ขั้นตอนการลงชื่อเข้าใช้ OpenID Connect ในแอปของคุณแล้ว คุณสามารถใช้โทเค็น ID โดยตรงเพื่อตรวจสอบสิทธิ์กับ Firebase:

สวิฟต์

let credential = OAuthProvider.credential(
    withProviderID: "oidc.example-provider",  // As registered in Firebase console.
    idToken: idToken,  // ID token from OpenID Connect flow.
    rawNonce: nil
)
Auth.auth().signIn(with: credential) { authResult, error in
    if error {
        // Handle error.
        return
    }
    // User is signed in.
    // IdP data available in authResult?.additionalUserInfo?.profile
}

วัตถุประสงค์-C

FIROAuthCredential *credential =
    [FIROAuthProvider credentialWithProviderID:@"oidc.example-provider"  // As registered in Firebase console.
                                       IDToken:idToken  // ID token from OpenID Connect flow.
                                      rawNonce:nil];
[[FIRAuth auth] signInWithCredential:credential
                          completion:^(FIRAuthDataResult * _Nullable authResult,
                                      NSError * _Nullable error) {
    if (error != nil) {
        // Handle error.
        return;
    }
    // User is signed in.
    // IdP data available in authResult.additionalUserInfo.profile
}];

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

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

  • ในแอปของคุณ คุณสามารถรับข้อมูลโปรไฟล์พื้นฐานของผู้ใช้ได้จากวัตถุ User ดู จัดการผู้ใช้

  • ใน กฎความปลอดภัย ของ Firebase Realtime Database และ Cloud Storage คุณสามารถรับ ID ผู้ใช้ที่ไม่ซ้ำกันของผู้ใช้ที่ลงชื่อเข้าใช้จากตัวแปร auth และใช้เพื่อควบคุมข้อมูลที่ผู้ใช้สามารถเข้าถึงได้

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

หากต้องการออกจากระบบผู้ใช้ ให้เรียก signOut:

สวิฟต์

let firebaseAuth = Auth.auth()
do {
  try firebaseAuth.signOut()
} catch let signOutError as NSError {
  print("Error signing out: %@", signOutError)
}

วัตถุประสงค์-C

NSError *signOutError;
BOOL status = [[FIRAuth auth] signOut:&signOutError];
if (!status) {
  NSLog(@"Error signing out: %@", signOutError);
  return;
}

คุณอาจต้องการเพิ่มรหัสการจัดการข้อผิดพลาดสำหรับข้อผิดพลาดการตรวจสอบสิทธิ์ทั้งหมด ดู จัดการข้อผิดพลาด