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

คุณอนุญาตให้ผู้ใช้ตรวจสอบสิทธิ์กับ Firebase ได้โดยใช้ผู้ให้บริการ OAuth เช่น Microsoft Azure Active Directory ด้วยการผสานรวมการเข้าสู่ระบบ OAuth ทั่วไปบนเว็บ เข้ามาในแอปโดยใช้ Firebase SDK เพื่อดำเนินการลงชื่อเข้าใช้ตั้งแต่ต้นทางถึงปลายทาง

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

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

  1. เพิ่ม Firebase ลงในโปรเจ็กต์ Apple
  2. ในคอนโซล Firebase ให้เปิดส่วน Auth
  3. เปิดใช้ผู้ให้บริการ Microsoft ในแท็บวิธีการลงชื่อเข้าใช้
  4. เพิ่มรหัสไคลเอ็นต์และรหัสลับไคลเอ็นต์จาก Play Console ของผู้ให้บริการรายนั้นลงใน การกำหนดค่าผู้ให้บริการ:
    1. หากต้องการลงทะเบียนไคลเอ็นต์ Microsoft OAuth ให้ทำตามคำแนะนำใน การเริ่มต้นอย่างรวดเร็ว: ลงทะเบียนแอปด้วยปลายทาง Azure Active Directory v2.0 โปรดทราบว่าปลายทางนี้รองรับการลงชื่อเข้าใช้โดยใช้บัญชีส่วนตัวของ Microsoft รวมถึง Azure บัญชี Active Directory ดูข้อมูลเพิ่มเติม เกี่ยวกับ Azure Active Directory v2.0
    2. เมื่อลงทะเบียนแอปกับผู้ให้บริการเหล่านี้ อย่าลืมลงทะเบียน โดเมน *.firebaseapp.com สำหรับโปรเจ็กต์ของคุณเป็นโดเมนการเปลี่ยนเส้นทางสำหรับ แอป
  5. คลิกบันทึก

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

หากต้องการจัดการขั้นตอนการลงชื่อเข้าใช้ด้วย SDK แพลตฟอร์ม Firebase ของ Apple ให้ทำตามขั้นตอนต่อไปนี้

  1. เพิ่มสคีม URL ที่กำหนดเองลงในโปรเจ็กต์ Xcode ของคุณดังนี้

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

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

      ภาพหน้าจอของอินเทอร์เฟซการตั้งค่ารูปแบบ URL ที่กําหนดเองของ Xcode
  2. สร้างอินสแตนซ์ของ OAuthProvider โดยใช้รหัสผู้ให้บริการ microsoft.com

    SwiftObjective-C
        var provider = OAuthProvider(providerID: "microsoft.com")
        
        FIROAuthProvider *provider = [FIROAuthProvider providerWithProviderID:@"microsoft.com"];
        
  3. ไม่บังคับ: ระบุพารามิเตอร์ OAuth ที่กำหนดเองเพิ่มเติมที่ต้องการ ส่งด้วยคำขอ OAuth

    SwiftObjective-C
        provider.customParameters = [
          "prompt": "consent",
          "login_hint": "user@firstadd.onmicrosoft.com"
        ]
        
        [provider setCustomParameters:@{@"prompt": @"consent", @"login_hint": @"user@firstadd.onmicrosoft.com"}];
        

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

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

    SwiftObjective-C
        provider.customParameters = [
          // Optional "tenant" parameter in case you are using an Azure AD
          // tenant. eg. '8eaef023-2b34-4da1-9baa-8bc8c9d6a490' or
          // 'contoso.onmicrosoft.com' or "common" for tenant-independent
          // tokens. The default value is "common".
          "tenant": "TENANT_ID"
        ]
        
        // Optional "tenant" parameter in case you are using an Azure AD tenant.
        // eg. '8eaef023-2b34-4da1-9baa-8bc8c9d6a490' or
        // 'contoso.onmicrosoft.com' or "common" for tenant-independent tokens.
        // The default value is "common".
        provider.customParameters = @{@"tenant": @"TENANT_ID"};
        
  4. ไม่บังคับ: ระบุขอบเขต OAuth 2.0 เพิ่มเติมที่นอกเหนือจากโปรไฟล์พื้นฐานที่ ที่ต้องการขอจากผู้ให้บริการตรวจสอบสิทธิ์

    SwiftObjective-C
        provider.scopes = ["mail.read", "calendars.read"]
        
        [provider setScopes:@[@"mail.read", @"calendars.read"]];
        

    ดูข้อมูลเพิ่มเติมได้ที่ เอกสารเกี่ยวกับสิทธิ์ของ Microsoft และความยินยอม

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

  6. ตรวจสอบสิทธิ์กับ Firebase โดยใช้ออบเจ็กต์ผู้ให้บริการ OAuth

    SwiftObjective-C
        // Replace nil with the custom class that conforms to AuthUIDelegate
        // you created in last step to use a customized web view.
        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
            }
          }
        }
        
        [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
            }];
          }
        }];
        

    ด้วยการใช้โทเค็นเพื่อการเข้าถึง OAuth คุณสามารถเรียก Microsoft Graph API

    ตัวอย่างเช่น หากต้องการดูข้อมูลโปรไฟล์พื้นฐาน คุณสามารถเรียกใช้ REST API การส่งโทเค็นเพื่อการเข้าถึงในส่วนหัว Authorization:

    https://graph.microsoft.com/v1.0/me

    Microsoft แตกต่างจากผู้ให้บริการรายอื่นที่ Firebase Auth รองรับ ระบุ URL รูปภาพ แต่ข้อมูลไบนารีสำหรับรูปโปรไฟล์จะต้อง ได้รับคำขอผ่าน Microsoft Graph API

    นอกเหนือจากโทเค็นเพื่อการเข้าถึง OAuth แล้ว OAuth ของผู้ใช้ โทเค็นรหัส สามารถดึงจากออบเจ็กต์ OAuthCredential ได้เช่นกัน การอ้างสิทธิ์ sub ในโทเค็นรหัสเป็นแบบเฉพาะแอปและจะไม่ตรงกับสมาพันธ์ ตัวระบุผู้ใช้ที่ Firebase Auth ใช้และเข้าถึงได้ผ่าน user.providerData[0].uid ดังนั้นควรใช้ช่องการอ้างสิทธิ์ oid แทน เมื่อใช้กลุ่มผู้ใช้ Azure AD ในการลงชื่อเข้าใช้ การอ้างสิทธิ์ oid จะมีลักษณะที่แน่นอน ที่ตรงกัน อย่างไรก็ตาม สำหรับกรณีที่ไม่ใช่กลุ่มผู้ใช้ ช่อง oid จะมีระยะห่างจากกัน สำหรับสมาพันธ์ รหัส 4b2eabcdefghijkl oid จะมีแบบฟอร์ม 00000000-0000-0000-4b2e-abcdefghijkl

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

    SwiftObjective-C
        Auth().currentUser.link(withCredential: credential) { authResult, error in
          if error != nil {
            // Handle error.
          }
          // Microsoft 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
        }
        
        [[FIRAuth auth].currentUser
            linkWithCredential:credential
                    completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
          if (error) {
            // Handle error.
          }
          // Microsoft 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 ซึ่งใช้เพื่อ เรียกข้อมูลข้อมูลเข้าสู่ระบบใหม่สำหรับการดำเนินการที่มีความละเอียดอ่อนซึ่งต้องใช้ไฟล์ล่าสุด เข้าสู่ระบบ

    SwiftObjective-C
        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
        }
        
        [[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
        }];
        

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

SwiftObjective-C
  // 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 Auth ไม่สนับสนุนความสามารถเดียวกันนี้สำหรับ ของผู้ให้บริการอย่าง Microsoft เนื่องจากไม่สามารถ เซิร์ฟเวอร์การตรวจสอบสิทธิ์เพื่อยืนยันกลุ่มเป้าหมายของโทเค็นเพื่อการเข้าถึงของ Microsoft OAuth ซึ่งเป็นข้อกำหนดด้านความปลอดภัยที่สำคัญมาก และอาจทำให้แอปพลิเคชัน เว็บไซต์ที่จะเล่นซ้ำโดยได้รับโทเค็นเพื่อการเข้าถึงของ Microsoft OAuth โปรเจ็กต์หนึ่ง (ผู้โจมตี) สามารถใช้เพื่อลงชื่อเข้าใช้โปรเจ็กต์อื่น (เหยื่อ) ได้ แต่ Firebase Auth ให้คุณจัดการขั้นตอน OAuth ทั้งหมดและ การแลกเปลี่ยนรหัสการให้สิทธิ์โดยใช้รหัสไคลเอ็นต์และข้อมูลลับของ OAuth ซึ่งกำหนดค่าไว้ในคอนโซล Firebase เนื่องจากรหัสการให้สิทธิ์สามารถใช้ได้เฉพาะ ร่วมกับรหัสไคลเอ็นต์/ข้อมูลลับเฉพาะ ซึ่งก็คือรหัสการให้สิทธิ์ ที่ได้รับสำหรับโครงการหนึ่ง จะไม่สามารถนำไปใช้กับอีกโครงการหนึ่งได้

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

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

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

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

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

หากต้องการนำผู้ใช้ออกจากระบบ โปรดโทร signOut:

SwiftObjective-C
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;
}

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