Xác thực bằng SSO Connect trong các ứng dụng web

Nếu đã nâng cấp lên Firebase Authentication with Identity Platform, bạn có thể xác thực người dùng bằng Firebase sử dụng nhà cung cấp theo chuẩn IDC (Open Connect Connect – OIDC) mà bạn đã chọn. Chiến dịch này giúp bạn có thể sử dụng nhà cung cấp danh tính không được Firebase hỗ trợ sẵn.

Trước khi bắt đầu

Để người dùng đăng nhập bằng nhà cung cấp OIDC (OpenID Connect), trước tiên, bạn phải thu thập một số thông tin từ nhà cung cấp:

  • Mã ứng dụng khách: Chuỗi duy nhất của nhà cung cấp giúp nhận dạng ứng dụng của bạn. Thông tin có thể chỉ định cho bạn một mã ứng dụng khách khác cho từng nền tảng mà bạn hỗ trợ. Đây là một trong các giá trị của thông báo xác nhận quyền sở hữu aud trong mã thông báo nhận dạng do Google Cloud.

  • Mật khẩu ứng dụng khách: Chuỗi bí mật mà nhà cung cấp sử dụng để xác nhận quyền sở hữu của một mã ứng dụng khách. Đối với mỗi mã ứng dụng khách, bạn cần có một mật khẩu ứng dụng khách trùng khớp. (Giá trị này chỉ bắt buộc nếu bạn đang sử dụng quy trình mã xác thực, tức là thực sự nên dùng.)

  • Công ty phát hành: Một chuỗi xác định nhà cung cấp. Giá trị này phải là một URL khi được nối với /.well-known/openid-configuration, sẽ là vị trí tài liệu khám phá OIDC (OpenID Connect) của nhà cung cấp. Ví dụ: nếu tổ chức phát hành là https://auth.example.com, tài liệu khám phá phải có tại https://auth.example.com/.well-known/openid-configuration.

Sau khi bạn có các thông tin trên, hãy kích hoạt OpenID Connect làm thông tin đăng nhập cho dự án Firebase của bạn:

  1. Thêm Firebase vào dự án JavaScript của bạn.

  2. Nếu bạn chưa nâng cấp lên Firebase Authentication with Identity Platform, hãy nâng cấp lên. Xác thực OpenID Connect chỉ có trong các dự án đã nâng cấp.

  3. Trên trang Nhà cung cấp dịch vụ đăng nhập của bảng điều khiển Firebase, nhấp vào Thêm nhà cung cấp mới, sau đó nhấp vào Kết nối OpenID.

  4. Chọn xem bạn sẽ sử dụng quy trình mã uỷ quyền hay quy trình cấp quyền ngầm ẩn.

    Bạn nên luôn sử dụng luồng mã nếu nhà cung cấp hỗ trợ luồng mã này. Chiến lược phát hành đĩa đơn luồng ngầm sẽ kém an toàn hơn và bạn không nên sử dụng luồng này.

  5. Đặt tên cho nhà cung cấp này. Lưu ý mã nhà cung cấp được tạo: chẳng hạn như oidc.example-provider. Bạn sẽ cần mã này khi thêm vào ứng dụng của mình.

  6. Chỉ định mã ứng dụng khách, mật khẩu ứng dụng khách và chuỗi nhà phát hành của nhà cung cấp. Các giá trị này phải khớp chính xác với giá trị mà nhà cung cấp đã chỉ định cho bạn.

  7. Lưu thay đổi.

Xử lý quy trình đăng nhập bằng Firebase SDK

Cách dễ nhất để xác thực người dùng với Firebase bằng OIDC (OpenID Connect) xử lý toàn bộ quy trình đăng nhập bằng Firebase SDK.

Để xử lý quy trình đăng nhập bằng SDK JavaScript của Firebase, hãy làm theo các bước sau các bước:

  1. Tạo một thực thể của OAuthProvider bằng mã nhà cung cấp mà bạn có trong đó bảng điều khiển của 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. Không bắt buộc: Chỉ định những thông số OAuth tuỳ chỉnh khác mà bạn muốn gửi cùng với yêu cầu 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'
    });
    

    Hãy liên hệ với nhà cung cấp của bạn để biết các tham số mà nhà cung cấp đó hỗ trợ. Lưu ý rằng bạn không thể chuyển các thông số bắt buộc của Firebase bằng setCustomParameters. Các tham số này là client_id, response_type, redirect_uri, state, scoperesponse_mode.

  3. Không bắt buộc: Chỉ định các phạm vi OAuth 2.0 khác ngoài hồ sơ cơ bản mà bạn muốn yêu cầu từ nhà cung cấp dịch vụ xác thực.

    Web

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

    Web

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

    Hãy liên hệ với nhà cung cấp của bạn để biết phạm vi mà nhà cung cấp đó hỗ trợ.

  4. Xác thực bằng Firebase bằng đối tượng nhà cung cấp OAuth.

    Bạn có thể chuyển hướng người dùng đến trang đăng nhập của nhà cung cấp hoặc mở trong cửa sổ trình duyệt bật lên.

    Quy trình chuyển hướng

    Chuyển hướng đến trang đăng nhập của nhà cung cấp bằng cách gọi signInWithRedirect():

    Web

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

    Web

    firebase.auth().signInWithRedirect(provider);
    

    Sau khi người dùng hoàn tất đăng nhập và quay lại ứng dụng của bạn, bạn có thể nhận được bằng cách gọi 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.
      });
    

    Quy trình bật lên

    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. Mặc dù các ví dụ ở trên tập trung vào quy trình đăng nhập, bạn có thể sử dụng cùng một để liên kết một nhà cung cấp OIDC (OpenID Connect) với người dùng hiện có bằng cách sử dụng linkWithRedirect()linkWithPopup(), đồng thời xác thực lại người dùng bằng reauthenticateWithRedirect()reauthenticateWithPopup(), có thể là dùng để truy xuất thông tin đăng nhập mới cho những hoạt động nhạy cảm cần đến lần đăng nhập gần đây.

Xử lý quy trình đăng nhập theo cách thủ công

Nếu đã triển khai quy trình đăng nhập bằng OpenID Connect trong ứng dụng của mình, bạn có thể sử dụng trực tiếp mã thông báo nhận dạng để xác thực với 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.
    });