如果您已升级到 Firebase Authentication with Identity Platform,则可以使用所选的 OpenID Connect (OIDC) 合规提供方对用户进行 Firebase 身份验证。这样,您就可以使用 Firebase 不提供原生支持的身份提供方。
准备工作
如需让用户使用 OIDC 提供方登录,您必须先从该提供方处收集一些信息:
客户端 ID:提供方用于标识您的应用的唯一字符串。您的提供方可能会针对您支持的每个平台为您分配一个不同的客户端 ID。这是您的提供方发放的 ID 令牌中的
aud
声明值之一。客户端密钥:提供方用于确认客户端 ID 所有权的密钥字符串。对于每个客户端 ID,您都需要一个匹配的客户端密钥。(仅当您使用身份验证代码流程 [强烈建议使用] 时才需要此值。)
发放者:用于标识您的提供方的字符串。此值必须是网址,在附加
/.well-known/openid-configuration
后表示提供方的 OIDC 发现文档的位置。例如,如果发放者为https://auth.example.com
,则发现文档必须在https://auth.example.com/.well-known/openid-configuration
位置提供。
获得上述信息后,启用 OpenID Connect 作为 Firebase 项目的登录提供方:
如果您尚未升级到 Firebase Authentication with Identity Platform,请升级。OpenID Connect 身份验证仅适用于升级后的项目。
在 Firebase 控制台的登录提供方页面上,点击添加新提供方,然后点击 OpenID Connect。
选择是要使用授权代码流程还是隐式授权流程。
如果提供方支持,您应始终使用代码流程。隐式流程的安全性较低,强烈建议不要使用。
为此提供方命名。请记下系统生成的提供方 ID(类似于
oidc.example-provider
)。向应用添加登录代码时,您需要用到此 ID。指定您的客户端 ID 和客户端密钥,以及提供方的发放者字符串。这些值必须与提供方分配给您的值完全一致。
保存更改。
使用 Firebase SDK 处理登录流程
如果您想要使用 OIDC 提供方通过 Firebase 验证用户身份,较简单的方法是使用 Firebase SDK 来处理整个登录流程。
如需使用 Firebase JavaScript SDK 处理登录流程,请按以下步骤操作:
使用您在 Firebase 控制台中获得的提供方 ID 创建
OAuthProvider
实例。Web
import { OAuthProvider } from "firebase/auth"; const provider = new OAuthProvider('oidc.example-provider');
Web
var provider = new firebase.auth.OAuthProvider('oidc.example-provider');
可选:指定您希望通过 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' });
请与您的提供方联系,了解其支持的参数。请注意,您不能使用
setCustomParameters
传递 Firebase 必需的参数。这些参数包括client_id
、response_type
、redirect_uri
、state
、scope
和response_mode
。可选:指定您希望向身份验证提供方申请获取的个人资料基本信息以外的额外 OAuth 2.0 范围。
Web
provider.addScope('mail.read'); provider.addScope('calendars.read');
Web
provider.addScope('mail.read'); provider.addScope('calendars.read');
请与您的提供方联系,了解其支持的范围。
使用 OAuth 提供方对象进行 Firebase 身份验证。
您可以将用户重定向到提供方的登录页面,也可以在弹出式浏览器窗口中打开登录页面。
重定向流程
调用
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. });
以上示例侧重的是登录流程。除此之外,您也可以使用同一模式通过
linkWithRedirect()
和linkWithPopup()
将 OIDC 提供方与现有用户相关联,然后使用reauthenticateWithRedirect()
和reauthenticateWithPopup()
(可用于为要求用户在近期登录的敏感操作检索新的凭据)重新验证用户身份。
手动处理登录流程
如果您已在应用中实现了 OpenID Connect 登录流程,可以直接使用 ID 令牌通过 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.
});