ตรวจสอบสิทธิ์โดยใช้ Microsoft ด้วย JavaScript

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

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

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

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

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

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

หากต้องการจัดการขั้นตอนการลงชื่อเข้าใช้ด้วย Firebase JavaScript SDK ให้ทําตามขั้นตอนต่อไปนี้

  1. สร้างอินสแตนซ์ของ OAuthProvider โดยใช้รหัสผู้ให้บริการ microsoft.com

    WebWeb
    import { OAuthProvider } from "firebase/auth";
    
    const provider = new OAuthProvider('microsoft.com');
    var provider = new firebase.auth.OAuthProvider('microsoft.com');
  2. ไม่บังคับ: ระบุพารามิเตอร์ OAuth ที่กำหนดเองเพิ่มเติมที่ต้องการส่งไปกับคําขอ OAuth

    WebWeb
    provider.setCustomParameters({
      // Force re-consent.
      prompt: 'consent',
      // Target specific email with login hint.
      login_hint: 'user@firstadd.onmicrosoft.com'
    });
    provider.setCustomParameters({
      // Force re-consent.
      prompt: 'consent',
      // Target specific email with login hint.
      login_hint: 'user@firstadd.onmicrosoft.com'
    });

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

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

    WebWeb
    provider.setCustomParameters({
      // 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'
    });
    provider.setCustomParameters({
      // 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'
    });
  3. ไม่บังคับ: ระบุขอบเขต OAuth 2.0 เพิ่มเติมนอกเหนือจากโปรไฟล์พื้นฐานที่คุณต้องการขอจากผู้ให้บริการตรวจสอบสิทธิ์

    provider.addScope('mail.read');
    provider.addScope('calendars.read');

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

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

    • หากต้องการลงชื่อเข้าใช้ด้วยหน้าต่างป๊อปอัป ให้โทรหา signInWithPopup
    WebWeb
    import { getAuth, signInWithPopup, OAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    signInWithPopup(auth, provider)
      .then((result) => {
        // User is signed in.
        // IdP data available in result.additionalUserInfo.profile.
    
        // Get the OAuth access token and ID Token
        const credential = OAuthProvider.credentialFromResult(result);
        const accessToken = credential.accessToken;
        const idToken = credential.idToken;
      })
      .catch((error) => {
        // Handle error.
      });
    firebase.auth().signInWithPopup(provider)
      .then((result) => {
        // IdP data available in result.additionalUserInfo.profile.
        // ...
    
        /** @type {firebase.auth.OAuthCredential} */
        var credential = result.credential;
    
        // OAuth access and id tokens can also be retrieved:
        var accessToken = credential.accessToken;
        var idToken = credential.idToken;
      })
      .catch((error) => {
        // Handle error.
      });
    • หากต้องการลงชื่อเข้าใช้โดยเปลี่ยนเส้นทางไปยังหน้าลงชื่อเข้าใช้ ให้โทรหา signInWithRedirect

    ทำตามแนวทางปฏิบัติแนะนำเมื่อใช้ signInWithRedirect, linkWithRedirect หรือ reauthenticateWithRedirect

    WebWeb
    import { getAuth, signInWithRedirect } from "firebase/auth";
    
    const auth = getAuth();
    signInWithRedirect(auth, provider);
    firebase.auth().signInWithRedirect(provider);

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

    WebWeb
    import { getAuth, getRedirectResult, OAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    getRedirectResult(auth)
      .then((result) => {
        // User is signed in.
        // IdP data available in result.additionalUserInfo.profile.
    
        // Get the OAuth access token and ID Token
        const credential = OAuthProvider.credentialFromResult(result);
        const accessToken = credential.accessToken;
        const idToken = credential.idToken;
      })
      .catch((error) => {
        // Handle error.
      });
    firebase.auth().getRedirectResult()
      .then((result) => {
        // IdP data available in result.additionalUserInfo.profile.
        // ...
    
        /** @type {firebase.auth.OAuthCredential} */
        var credential = result.credential;
    
        // OAuth access and id tokens can also be retrieved:
        var accessToken = credential.accessToken;
        var idToken = credential.idToken;
      })
      .catch((error) => {
        // Handle error.
      });

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

    คุณเรียกใช้ Microsoft Graph API ได้โดยใช้โทเค็นการเข้าถึง OAuth

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

    curl -i -H "Authorization: Bearer ACCESS_TOKEN" https://graph.microsoft.com/v1.0/me

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

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

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

    WebWeb
    import { getAuth, linkWithPopup, OAuthProvider } from "firebase/auth";
    
    const provider = new OAuthProvider('microsoft.com');
    const auth = getAuth();
    
    linkWithPopup(auth.currentUser, provider)
        .then((result) => {
          // Microsoft credential is linked to the current user.
          // IdP data available in result.additionalUserInfo.profile.
    
          // Get the OAuth access token and ID Token
          const credential = OAuthProvider.credentialFromResult(result);
          const accessToken = credential.accessToken;
          const idToken = credential.idToken;
        })
        .catch((error) => {
          // Handle error.
        });
    var provider = new firebase.auth.OAuthProvider('microsoft.com');
    firebase.auth().currentUser.linkWithPopup(provider)
        .then((result) => {
          // Microsoft credential is linked to the current user.
          // IdP data available in result.additionalUserInfo.profile.
          // OAuth access token can also be retrieved:
          // result.credential.accessToken
          // OAuth ID token can also be retrieved:
          // result.credential.idToken
        })
        .catch((error) => {
          // Handle error.
        });
  6. คุณสามารถใช้รูปแบบเดียวกันกับ reauthenticateWithPopup/reauthenticateWithRedirect ซึ่งจะใช้เพื่อดึงข้อมูลเข้าสู่ระบบใหม่สำหรับการดำเนินการที่มีความละเอียดอ่อนซึ่งต้องมีการเข้าสู่ระบบครั้งล่าสุดได้

    WebWeb
    import { getAuth, reauthenticateWithPopup, OAuthProvider } from "firebase/auth";
    
    const provider = new OAuthProvider('microsoft.com');
    const auth = getAuth();
    reauthenticateWithPopup(auth.currentUser, provider)
        .then((result) => {
          // 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.
    
          // Get the OAuth access token and ID Token
          const credential = OAuthProvider.credentialFromResult(result);
          const accessToken = credential.accessToken;
          const idToken = credential.idToken;
        })
        .catch((error) => {
          // Handle error.
        });
    var provider = new firebase.auth.OAuthProvider('microsoft.com');
    firebase.auth().currentUser.reauthenticateWithPopup(provider)
        .then((result) => {
          // 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.
          // OAuth access token can also be retrieved:
          // result.credential.accessToken
          // OAuth ID token can also be retrieved:
          // result.credential.idToken
        })
        .catch((error) => {
          // Handle error.
        });

หากคุณเปิดใช้การตั้งค่าบัญชี 1 บัญชีต่ออีเมล 1 รายการในคอนโซล Firebase เมื่อผู้ใช้พยายามลงชื่อเข้าใช้ผู้ให้บริการ (เช่น Microsoft) ด้วยอีเมลที่มีอยู่แล้วสำหรับผู้ให้บริการของผู้ใช้ Firebase รายอื่น (เช่น Google) ระบบจะแสดงข้อผิดพลาด auth/account-exists-with-different-credential พร้อมกับออบเจ็กต์ AuthCredential (ข้อมูลเข้าสู่ระบบ Microsoft) หากต้องการลงชื่อเข้าใช้ผู้ให้บริการที่ต้องการให้เสร็จสมบูรณ์ ผู้ใช้ต้องลงชื่อเข้าใช้ผู้ให้บริการที่มีอยู่ (Google) ก่อน แล้วจึงลิงก์กับ AuthCredential เดิม (ข้อมูลเข้าสู่ระบบ Microsoft)

หากใช้ signInWithPopup คุณจะจัดการข้อผิดพลาด auth/account-exists-with-different-credential ได้ด้วยโค้ด เช่นตัวอย่างต่อไปนี้

import {
  getAuth,
  linkWithCredential,
  signInWithPopup,
  OAuthProvider,
} from "firebase/auth";

try {
  // Step 1: User tries to sign in using Microsoft.
  let result = await signInWithPopup(getAuth(), new OAuthProvider());
} catch (error) {
  // Step 2: User's email already exists.
  if (error.code === "auth/account-exists-with-different-credential") {
    // The pending Microsoft credential.
    let pendingCred = error.credential;

    // Step 3: Save the pending credential in temporary storage,

    // Step 4: Let the user know that they already have an account
    // but with a different provider, and let them choose another
    // sign-in method.
  }
}

// ...

try {
  // Step 5: Sign the user in using their chosen method.
  let result = await signInWithPopup(getAuth(), userSelectedProvider);

  // Step 6: Link to the Microsoft credential.
  // TODO: implement `retrievePendingCred` for your app.
  let pendingCred = retrievePendingCred();

  if (pendingCred !== null) {
    // As you have access to the pending credential, you can directly call the
    // link method.
    let user = await linkWithCredential(result.user, pendingCred);
  }

  // Step 7: Continue to app.
} catch (error) {
  // ...
}

โหมดเปลี่ยนเส้นทาง

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

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

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

ตรวจสอบสิทธิ์ด้วย Firebase ในส่วนขยาย Chrome

หากคุณกำลังสร้างแอปส่วนขยาย Chrome โปรดดู คำแนะนำเกี่ยวกับเอกสารที่อยู่นอกหน้าจอ

เมื่อสร้างโปรเจ็กต์ Firebase จะจัดสรรโดเมนย่อยที่ไม่ซ้ำกันให้กับโปรเจ็กต์ ดังนี้ https://my-app-12345.firebaseapp.com

ซึ่งจะใช้เป็นกลไกการเปลี่ยนเส้นทางสำหรับการลงชื่อเข้าใช้ OAuth ด้วย โดเมนดังกล่าวจะต้องได้รับอนุญาตให้ใช้กับผู้ให้บริการ OAuth ทั้งหมดที่รองรับ อย่างไรก็ตาม การดำเนินการนี้หมายความว่าผู้ใช้อาจเห็นโดเมนดังกล่าวขณะลงชื่อเข้าใช้ Microsoft ก่อนที่จะเปลี่ยนเส้นทางกลับไปยังแอปพลิเคชัน ต่อไปที่: https://my-app-12345.firebaseapp.com

หากไม่ต้องการให้ระบบแสดงโดเมนย่อย คุณสามารถตั้งค่าโดเมนที่กำหนดเองกับ Firebase Hosting ได้โดยทำดังนี้

  1. ทำตามขั้นตอนที่ 1-3 ในหัวข้อตั้งค่าโดเมนสำหรับ Hosting เมื่อคุณยืนยันการเป็นเจ้าของโดเมน Hosting จะจัดสรรใบรับรอง SSL สำหรับโดเมนที่กำหนดเอง
  2. เพิ่มโดเมนที่กำหนดเองลงในรายการโดเมนที่ได้รับอนุญาตในคอนโซล Firebase: auth.custom.domain.com
  3. ใน Microsoft Developer Console หรือหน้าการตั้งค่า OAuth ให้เพิ่ม URL ของหน้าเปลี่ยนเส้นทางในรายการที่อนุญาต ซึ่งจะเข้าถึงได้ในโดเมนที่กำหนดเอง https://auth.custom.domain.com/__/auth/handler
  4. เมื่อเริ่มต้นใช้งานไลบรารี JavaScript ให้ระบุโดเมนที่กำหนดเองด้วยช่อง authDomain ดังนี้
    var config = {
      apiKey: '...',
      // Changed from 'PROJECT_ID.firebaseapp.com'.
      authDomain: 'auth.custom.domain.com',
      databaseURL: 'https://PROJECT_ID.firebaseio.com',
      projectId: 'PROJECT_ID',
      storageBucket: 'PROJECT_ID.firebasestorage.app',
      messagingSenderId: 'SENDER_ID'
    };
    firebase.initializeApp(config);

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

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

  • ในแอปทําตามวิธีที่เราแนะนําเพื่อดูสถานะการตรวจสอบสิทธิ์ของผู้ใช้คือการตั้งค่าผู้สังเกตการณ์ในออบเจ็กต์ Auth จากนั้นคุณก็รับข้อมูลโปรไฟล์พื้นฐานของผู้ใช้ได้จากออบเจ็กต์ User โปรดดูหัวข้อจัดการผู้ใช้

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

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

หากต้องการออกจากระบบของผู้ใช้ ให้เรียกใช้ signOut โดยทำดังนี้

WebWeb
import { getAuth, signOut } from "firebase/auth";

const auth = getAuth();
signOut(auth).then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});
firebase.auth().signOut().then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});