您可以将 Twitter 身份验证机制集成到您的应用中,让您的用户可使用自己的 Twitter 帐号进行 Firebase 身份验证。集成 Twitter 身份验证的方法有两种:使用 Firebase SDK 执行登录流程;手动执行 Twitter OAuth 流程并将生成的访问令牌和密钥传递给 Firebase。
准备工作
- 将 Firebase 添加至您的 JavaScript 项目。
- 在 Firebase 控制台中,打开 Auth 部分。
- 在 Sign in method(登录方法)标签页中,启用 Twitter 提供方。
- 将该提供方的开发者控制台中的 API 密钥和 API 密文添加至提供方配置:
- 在 Twitter 上将您的应用注册为开发者应用,并获取应用的 OAuth API 密钥和 API 密文。
- 请务必前往 Twitter 应用配置,在您应用的设置页面中,将 Firebase OAuth 重定向 URI(例如
my-app-12345.firebaseapp.com/__/auth/handler
)设置为您的授权回调网址。
- 点击保存。
使用 Firebase SDK 处理登录流程
如果您是在构建 Web 应用,想要通过用户的 Twitter 帐号对其进行 Firebase 身份验证,最简单的方法是使用 Firebase JavaScript SDK 来处理登录流程(如果您希望在 Node.js 或其他非浏览器环境中对用户进行身份验证,则必须手动处理登录流程。)
如需使用 Firebase JavaScript SDK 处理登录流程,请按以下步骤操作:
- 创建 Twitter 提供方对象实例:
Web 模块化 API
import { TwitterAuthProvider } from "firebase/auth"; const provider = new TwitterAuthProvider();
Web 命名空间型 API
var provider = new firebase.auth.TwitterAuthProvider();
- 可选:如需将提供方的 OAuth 流程本地化为用户偏好的语言,而不明确传递相关自定义 OAuth 参数,请在启动 OAuth 流程之前先更新 Auth 实例中的语言代码。例如:
Web 模块化 API
import { getAuth } from "firebase/auth"; const auth = getAuth(); auth.languageCode = 'it'; // To apply the default browser preference instead of explicitly setting it. // auth.useDeviceLanguage();
Web 命名空间型 API
firebase.auth().languageCode = 'it'; // To apply the default browser preference instead of explicitly setting it. // firebase.auth().useDeviceLanguage();
- 可选:指定您希望通过 OAuth 请求发送的其他自定义 OAuth 提供方参数。如需添加自定义参数,请使用包含 OAuth 提供方文档中指定的键及相应值的对象,对已初始化的提供方调用
setCustomParameters
方法。例如:Web 模块化 API
provider.setCustomParameters({ 'lang': 'es' });
Web 命名空间型 API
provider.setCustomParameters({ 'lang': 'es' });
- 使用 Twitter 提供方对象进行 Firebase 身份验证。您可以打开弹出式窗口或将用户重定向至登录页面,提示用户使用自己的 Twitter 帐号登录。在移动设备上最好使用重定向方法。
- 如需使用弹出式窗口登录,请调用
signInWithPopup
:Web 模块化 API
import { getAuth, signInWithPopup, TwitterAuthProvider } from "firebase/auth"; const auth = getAuth(); signInWithPopup(auth, provider) .then((result) => { // This gives you a the Twitter OAuth 1.0 Access Token and Secret. // You can use these server side with your app's credentials to access the Twitter API. const credential = TwitterAuthProvider.credentialFromResult(result); const token = credential.accessToken; const secret = credential.secret; // The signed-in user info. const user = result.user; // IdP data available using getAdditionalUserInfo(result) // ... }).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 = TwitterAuthProvider.credentialFromError(error); // ... });
Web 命名空间型 API
firebase .auth() .signInWithPopup(provider) .then((result) => { /** @type {firebase.auth.OAuthCredential} */ var credential = result.credential; // This gives you a the Twitter OAuth 1.0 Access Token and Secret. // You can use these server side with your app's credentials to access the Twitter API. var token = credential.accessToken; var secret = credential.secret; // The signed-in user info. var user = result.user; // IdP data available in result.additionalUserInfo.profile. // ... }).catch((error) => { // Handle Errors here. var errorCode = error.code; var errorMessage = error.message; // The email of the user's account used. var email = error.email; // The firebase.auth.AuthCredential type that was used. var credential = error.credential; // ... });
您还可以在此处捕获并处理错误。如需获取错误代码列表,请参阅身份验证参考文档。
- 需重定向到登录页面进行登录,请调用
signInWithRedirect
:使用“signInWithRedirect”时,请遵循最佳实践。Web 模块化 API
import { getAuth, signInWithRedirect } from "firebase/auth"; const auth = getAuth(); signInWithRedirect(auth, provider);
Web 命名空间型 API
firebase.auth().signInWithRedirect(provider);
getRedirectResult
来检索 Twitter 提供方的 OAuth 令牌:Web 模块化 API
import { getAuth, getRedirectResult, TwitterAuthProvider } from "firebase/auth"; const auth = getAuth(); getRedirectResult(auth) .then((result) => { // This gives you a the Twitter OAuth 1.0 Access Token and Secret. // You can use these server side with your app's credentials to access the Twitter API. const credential = TwitterAuthProvider.credentialFromResult(result); const token = credential.accessToken; const secret = credential.secret; // ... // The signed-in user info. const user = result.user; // IdP data available using getAdditionalUserInfo(result) // ... }).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 = TwitterAuthProvider.credentialFromError(error); // ... });
Web 命名空间型 API
firebase.auth() .getRedirectResult() .then((result) => { if (result.credential) { /** @type {firebase.auth.OAuthCredential} */ var credential = result.credential; // This gives you a the Twitter OAuth 1.0 Access Token and Secret. // You can use these server side with your app's credentials to access the Twitter API. var token = credential.accessToken; var secret = credential.secret; // ... } // The signed-in user info. var user = result.user; // IdP data available in result.additionalUserInfo.profile. // ... }).catch((error) => { // Handle Errors here. var errorCode = error.code; var errorMessage = error.message; // The email of the user's account used. var email = error.email; // The firebase.auth.AuthCredential type that was used. var credential = error.credential; // ... });
- 如需使用弹出式窗口登录,请调用
手动处理登录流程
您还可以通过调用 Twitter OAuth 端点来处理登录流程,从而使用 Twitter 帐号进行 Firebase 身份验证:
- 按开发者文档中的说明操作,将 Twitter 登录服务集成到您的应用中。在 Twitter 登录流程结束后,您会收到一个 OAuth 访问令牌和一个 OAuth 密钥。
- 如果您需要在 Node.js 应用上登录,请将 OAuth 访问令牌和 OAuth 密钥发送到 Node.js 应用。
- 在用户使用 Twitter 成功登录后,用 OAuth 访问令牌和 OAuth 密钥换取 Firebase 凭据:
var credential = firebase.auth.TwitterAuthProvider.credential(token, secret);
- 最后,使用 Firebase 凭据进行 Firebase 身份验证:
Web 模块化 API
import { getAuth, signInWithCredential, FacebookAuthProvider } from "firebase/auth"; // Sign in with the credential from the Facebook user. const auth = getAuth(); signInWithCredential(auth, credential) .then((result) => { // Signed in const credential = FacebookAuthProvider.credentialFromResult(result); }) .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 = FacebookAuthProvider.credentialFromError(error); // ... });
Web 命名空间型 API
// Sign in with the credential from the Facebook user. firebase.auth().signInWithCredential(credential) .then((result) => { // Signed in var credential = result.credential; // ... }) .catch((error) => { // Handle Errors here. var errorCode = error.code; var errorMessage = error.message; // The email of the user's account used. var email = error.email; // The firebase.auth.AuthCredential type that was used. var credential = error.credential; // ... });
在 Chrome 扩展程序中进行 Firebase 身份验证
如果您是在构建 Chrome 扩展程序应用,则必须添加 Chrome 扩展程序 ID:
- 在 Firebase 控制台中打开您的项目。
- 在 Authentication 部分中,打开登录方法页面。
- 向“已获授权的网域”列表添加格式如下的 URI:
chrome-extension://CHROME_EXTENSION_ID
由于 Chrome 扩展程序无法使用 HTTP 重定向,因此只能使用弹出式操作方式(signInWithPopup
、linkWithPopup
和 reauthenticateWithPopup
)。您应该从后台页面脚本而不是弹出式窗口(浏览器操作)中调用这些方法,因为身份验证的弹出式窗口将取消浏览器操作的弹出式窗口。弹出式操作方式只能在使用 Manifest V2 的扩展程序中使用。较新的 Manifest V3 只允许采用 Service Worker 形式的后台脚本,无法执行弹出式操作方式。
在 Chrome 扩展程序的清单文件中,确保将 https://apis.google.com
网址加入 content_security_policy
许可名单中。
后续步骤
在用户首次登录后,系统会创建一个新的用户帐号,并将其与该用户登录时使用的凭据(即用户名和密码、电话号码或者身份验证提供方信息)相关联。此新帐号存储在您的 Firebase 项目中,无论用户采用何种方式登录,您项目中的每个应用都可以使用此帐号来识别用户。
-
在您的应用中,建议通过在
Auth
对象上设置观测者 (observer) 来了解用户的身份验证状态。然后,您便可从User
对象获取用户的基本个人资料信息。请参阅管理用户。 在您的 Firebase Realtime Database 和 Cloud Storage 安全规则中,您可以从
auth
变量获取已登录用户的唯一用户 ID,然后利用此 ID 来控制用户可以访问哪些数据。
您可以将多个身份验证提供方凭据与一个现有用户帐号关联,让用户可以使用多个身份验证提供方登录您的应用。
如需让用户退出登录,请调用 signOut
:
Web 模块化 API
import { getAuth, signOut } from "firebase/auth"; const auth = getAuth(); signOut(auth).then(() => { // Sign-out successful. }).catch((error) => { // An error happened. });
Web 命名空间型 API
firebase.auth().signOut().then(() => { // Sign-out successful. }).catch((error) => { // An error happened. });