ตรวจสอบสิทธิ์โดยใช้ OpenID Connect ในเว็บแอป

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

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

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

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

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

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

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

  1. เพิ่ม Firebase ลงในโปรเจ็กต์ JavaScript

  2. หากยังไม่ได้อัปเกรดเป็น Firebase Authentication with Identity Platform ให้อัปเกรด OpenID Connect authentication จะใช้ได้ในโปรเจ็กต์ที่อัปเกรดแล้วเท่านั้น

  3. ในหน้าผู้ให้บริการลงชื่อเข้าใช้ ของคอนโซลFirebaseให้คลิกAdd new providerแล้วคลิก OpenID Connect

  4. เลือกว่าจะใช้ ขั้นตอนรหัสการให้สิทธิ์ หรือ ขั้นตอนการให้สิทธิ์โดยนัย

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

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

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

  7. บันทึกการเปลี่ยนแปลง

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

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

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

  1. สร้างอินสแตนซ์ของ OAuthProvider โดยใช้รหัสผู้ให้บริการที่คุณได้รับในคอนโซล Firebase

    Web

    import { OAuthProvider } from "firebase/auth";
    
    const provider = new OAuthProvider('oidc.example-provider');
    

    Web

    var provider = new firebase.auth.OAuthProvider('oidc.example-provider');
    
  2. ไม่บังคับ: ระบุพารามิเตอร์ OAuth ที่กำหนดเองเพิ่มเติมที่ต้องการ ส่งพร้อมกับคำขอ OAuth

    Web

    provider.setCustomParameters({
      // Target specific email with login hint.
      login_hint: 'user@example.com'
    });
    

    Web

    provider.setCustomParameters({
      // Target specific email with login hint.
      login_hint: 'user@example.com'
    });
    

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

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

    Web

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

    Web

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

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

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

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

    ขั้นตอนการเปลี่ยนเส้นทาง

    เปลี่ยนเส้นทางไปยังหน้าลงชื่อเข้าใช้ของผู้ให้บริการโดยเรียกใช้ signInWithRedirect()

    Web

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

    Web

    firebase.auth().signInWithRedirect(provider);
    

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

    Web

    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.
      });
    

    Web

    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.
      });
    

    ขั้นตอนป๊อปอัป

    Web

    import { getAuth, signInWithPopup, OAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    signInWithPopup(auth, provider)
      .then((result) => {
        // User is signed in.
        // IdP data available using getAdditionalUserInfo(result)
    
        // 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.
      });
    

    Web

    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.
      });
    
  5. แม้ว่าตัวอย่างข้างต้นจะเน้นที่ขั้นตอนการลงชื่อเข้าใช้ แต่คุณสามารถใช้รูปแบบเดียวกันเพื่อลิงก์ผู้ให้บริการ OIDC กับผู้ใช้ที่มีอยู่โดยใช้ linkWithRedirect() และ linkWithPopup() รวมถึงตรวจสอบสิทธิ์ผู้ใช้อีกครั้งด้วย reauthenticateWithRedirect() และ reauthenticateWithPopup() ซึ่งใช้เพื่อดึงข้อมูลเข้าสู่ระบบใหม่สำหรับการดำเนินการที่ละเอียดอ่อนซึ่งต้องมีการเข้าสู่ระบบล่าสุด

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

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

Web

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

const provider = new OAuthProvider("oidc.example-provider");
const credential = provider.credential({
    idToken: idToken,
});
signInWithCredential(getAuth(), credential)
    .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.
    });

Web

const provider = new OAuthProvider("oidc.example-provider");
const credential = provider.credential({
    idToken: idToken,
});
firebase.auth().signInWithCredential(credential)
    .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.
    });