透過 OIDC 登入使用者
本文說明如何使用 Identity Platform,透過 OpenID Connect (OIDC) 提供者登入使用者帳戶。
事前準備
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
- 啟用 Identity Platform,並將用戶端 SDK 新增至應用程式。如要瞭解做法,請參閱快速入門。
前往 Google Cloud 控制台的「Identity Providers」(識別資訊提供者) 頁面。
前往「Identity Providers」(識別資訊提供者) 頁面按一下「新增供應商」,然後從清單中選取「OpenID Connect」。
輸入下列詳細資料,啟用授權碼流程:
在「選擇授權類型」部分下方,選取「程式碼流程」。
供應商名稱。這可以與供應商 ID 相同,也可以是自訂名稱。如果輸入自訂名稱,請按一下「供應商 ID」旁的「編輯」,指定 ID (必須以
oidc.
開頭)。供應商的用戶端 ID。
供應商的「核發單位」。這應該會類似
https://example.com
。Identity Platform 會使用這個網址尋找 OIDC 探索文件 (通常位於/.well-known/openid-configuration
),該文件會指定供應商的 OAuth 端點和公開金鑰。供應商的用戶端密鑰。
將應用程式新增至「已授權網域」清單。舉例來說,如果應用程式的登入網址為
https://example.com/login
,請新增example.com
。向 OIDC 供應商設定 Identity Platform 回呼網址做為重新導向網址。網址應類似於
https://[PROJECT-ID].firebaseapp.com/__/auth/handler
。按一下 [儲存]。
輸入下列詳細資料,啟用隱含流程:
在「Choose grant type」(選擇授權類型) 部分下方,選取「Implicit Flow」(隱含流程)。
供應商名稱。這可以與供應商 ID 相同,也可以是自訂名稱。如果輸入自訂名稱,請按一下「供應商 ID」旁的「編輯」,指定 ID (必須以
oidc.
開頭)。供應商的用戶端 ID。
供應商的「核發單位」。這看起來應該會像這樣:
https://example.com.
Identity Platform 會使用這個網址尋找 OIDC 探索文件 (通常位於/.well-known/openid-configuration
),該文件會指定供應商的 OAuth 端點和公開金鑰。
將應用程式新增至「已授權網域」清單。舉例來說,如果應用程式的登入網址為
https://example.com/login
,請新增example.com
。向 OIDC 供應商設定 Identity Platform 回呼網址做為重新導向網址。網址應類似於
https://[PROJECT-ID].firebaseapp.com/__/auth/handler
。按一下 [儲存]。
使用 OAuth 流程。這樣一來,系統就會為您完成 OAuth 握手程序。根據設定供應商步驟中選取的授權碼流程/隱含流程,GCIP 伺服器會選擇與身分識別供應商通訊的所需流程。
使用 OIDC 供應商的 ID 權杖。這個方法假設您已取得 OIDC 權杖。
使用您在前一節中設定的供應商 ID,建立
OAuthProvider
執行個體。提供者 ID 的開頭必須是oidc.
。網頁版 9
import { OAuthProvider } from "firebase/auth"; const provider = new OAuthProvider("oidc.myProvider");
網頁版 8
const provider = new firebase.auth.OAuthProvider('oidc.myProvider');
啟動登入流程。你可以選擇使用彈出式視窗或重新導向。
彈出式視窗
網頁版 9
import { getAuth, signInWithPopup, OAuthProvider } from "firebase/auth"; const auth = getAuth(); signInWithPopup(auth, provider) .then((result) => { // User is signed in. const credential = OAuthProvider.credentialFromResult(result); // This gives you an access token for the OIDC provider. You can use it to directly interact with that provider }).catch((error) => { // Handle Errors here. const errorCode = error.code; const errorMessage = error.message; // The email of the user's account used. const email = error.customData.email; // The AuthCredential type that was used. const credential = OAuthProvider.credentialFromError(error); // Handle / display error. // ... });
網頁版 8
firebase.auth().signInWithPopup(provider) .then((result) => { // User is signed in. // result.credential is a firebase.auth().OAuthCredential object. // result.credential.providerId is equal to 'oidc.myProvider'. // result.credential.idToken is the OIDC provider's ID token. }) .catch((error) => { // Handle error. });
重新導向
如要重新導向至登入頁面,請呼叫
signInWithRedirect()
:網頁版 9
import { getAuth, signInWithRedirect } from "firebase/auth"; const auth = getAuth(); signInWithRedirect(auth, provider);
網頁版 8
firebase.auth().signInWithRedirect(provider).catch((error) => { // Handle error. });
接著,在使用者返回應用程式時呼叫
getRedirectResult()
取得結果:網頁版 9
import { getAuth, getRedirectResult, OAuthProvider } from "firebase/auth"; const auth = getAuth(); getRedirectResult(auth) .then((result) => { // User is signed in. const credential = OAuthProvider.credentialFromResult(result); // This gives you an access token for the OIDC provider. You can use it to directly interact with that provider }) .catch((error) => { // Handle Errors here. const errorCode = error.code; const errorMessage = error.message; // The email of the user's account used. const email = error.customData.email; // The AuthCredential type that was used. const credential = OAuthProvider.credentialFromError(error); // Handle / display error. // ... });
網頁版 8
// On return. firebase.auth().getRedirectResult() .then((result) => { // User is signed in. // result.credential is a firebase.auth().OAuthCredential object. // result.credential.providerId is equal to 'oidc.myProvider'. // result.credential.idToken is the OIDC provider's ID token. }) .catch((error) => { // Handle / display error. // ... });
使用您在前一節中設定的提供者 ID,初始化
OAuthProvider
執行個體。提供者 ID 的開頭必須是oidc.
。接著建立OAuthCredential
,並呼叫signInWithCredential()
讓使用者登入。網頁版 9
import { getAuth, OAuthProvider, signInWithCredential } from "firebase/auth"; const auth = getAuth(); const credential = provider.credential({ idToken: oidcIdToken, }); signInWithCredential(auth, credential) .then((result) => { // User is signed in. const newCredential = OAuthProvider.credentialFromResult(result); // This gives you a new access token for the OIDC provider. You can use it to directly interact with that provider. }) .catch((error) => { // Handle Errors here. const errorCode = error.code; const errorMessage = error.message; // The email of the user's account used. const email = error.customData.email; // The AuthCredential type that was used. const credential = OAuthProvider.credentialFromError(error); // Handle / display error. // ... });
網頁版 8
const credential = provider.credential(oidcIdToken, null); firebase.auth().signInWithCredential(credential) .then((result) => { // User is signed in. // User now has a odic.myProvider UserInfo in providerData. }) .catch((error) => { // Handle / display error. // ... });
設定提供者
授權碼流程
隱含流程
登入的使用者
透過 OIDC 登入使用者的方式有兩種:
透過 OAuth 登入使用者
如要使用 OAuth 登入,請按照下列步驟操作:
任一流程結束後,您可以使用 result.credential.idToken
欄位取得 OIDC ID 權杖。
直接登入使用者
如要直接使用 OIDC ID 權杖登入使用者,請按照下列步驟操作:
連結使用者帳戶
如果使用者已透過其他方法 (例如電子郵件/密碼) 登入應用程式,您可以使用 linkWithPopup()
或 linkWithRedirect()
,將現有帳戶連結至 OIDC 供應商:
舉例來說,我們可以連結至 Google 帳戶:
網頁版 9
import { getAuth, linkWithPopup, GoogleAuthProvider } from "firebase/auth"; const provider = new GoogleAuthProvider(); const auth = getAuth(); linkWithPopup(auth.currentUser, provider).then((result) => { // Accounts successfully linked. const credential = GoogleAuthProvider.credentialFromResult(result); const user = result.user; // ... }).catch((error) => { // Handle Errors here. // ... });
網頁版 8
auth.currentUser.linkWithPopup(provider).then((result) => { // Accounts successfully linked. var credential = result.credential; var user = result.user; // ... }).catch((error) => { // Handle Errors here. // ... });