我们编写本指南是因为 Google 的官方指南缺少一些重要步骤,我们在下面链接了:
在 Chrome 扩展程序中使用 Firebase 进行身份验证
这适用于任何操作系统。出于本指南的目的,我们将使用 Mac OS
a) 为您的项目创建一个新目录:
mkdir firebase-chrome-auth cd firebase-chrome-auth
b) 创建两个子目录:
mkdir chrome-extension mkdir firebase-project
a) 转到 Firebase 控制台。
b)点击“添加项目”并按照步骤创建一个新项目。
c) 创建后,单击“Web”将 Web 应用程序添加到您的项目。
d) 使用昵称注册您的应用(例如“Chrome 扩展程序身份验证”)。
e) 复制 Firebase 配置对象。稍后你会需要这个。
const firebaseConfig = { apiKey: "example", authDomain: "example.firebaseapp.com", projectId: "example", storageBucket: "example", messagingSenderId: "example", appId: "example" };
f) 导航到 firebase-project 目录
cd firebase-project
g) 初始化一个新的 npm 项目
npm init -y
h) 安装 Firebase:
npm 安装 firebase
i) 在 firebase-project/index.html
中创建一个 index.html 文件
<!DOCTYPE html> <html> <head> <title>Firebase Auth for Chrome Extension</title> </head> <body> <h1>Firebase Auth for Chrome Extension</h1> <script type="module" src="signInWithPopup.js"></script> </body> </html>
j) 在 firebase-project/signInWithPopup.js
中创建一个signInWithPopup.js 文件
import { initializeApp } from 'firebase/app'; import { getAuth, signInWithPopup, GoogleAuthProvider } from 'firebase/auth'; const firebaseConfig = { // Your web app's Firebase configuration // Replace with the config you copied from Firebase Console }; const app = initializeApp(firebaseConfig); const auth = getAuth(); // This gives you a reference to the parent frame, i.e. the offscreen document. const PARENT_FRAME = document.location.ancestorOrigins[0]; const PROVIDER = new GoogleAuthProvider(); function sendResponse(result) { window.parent.postMessage(JSON.stringify(result), PARENT_FRAME); } window.addEventListener('message', function({data}) { if (data.initAuth) { signInWithPopup(auth, PROVIDER) .then(sendResponse) .catch(sendResponse); } });
k) 部署 Firebase 项目
npm install -g firebase-tools firebase login firebase init hosting firebase deploy
请注意部署后提供的托管 URL。 Chrome 扩展程序需要它。
a) 导航到 chrome-extension 目录
cd ../chrome-extension
b) 在chrome-extension/manifest.json
中创建一个manifest.json文件
{ "manifest_version": 3, "name": "Firebase Auth Extension", "version": "1.0", "description": "Chrome extension with Firebase Authentication", "permissions": [ "identity", "storage", "offscreen" ], "host_permissions": [ "https://*.firebaseapp.com/*" ], "background": { "service_worker": "background.js", "type": "module" }, "action": { "default_popup": "popup.html" }, "web_accessible_resources": [ { "resources": ["offscreen.html"], "matches": ["<all_urls>"] } ], "oauth2": { "client_id": "YOUR-ID.apps.googleusercontent.com", "scopes": [ "openid", "email", "profile" ] }, "key": "-----BEGIN PUBLIC KEY-----\nYOURPUBLICKEY\n-----END PUBLIC KEY-----" }
c) 在 chrome-extension/popup.html
中创建 popup.html 文件
<!DOCTYPE html> <html> <head> <title>Firebase Auth Extension</title> </head> <body> <h1>Firebase Auth Extension</h1> <div id="userInfo"></div> <button id="signInButton">Sign In</button> <button id="signOutButton" style="display:none;">Sign Out</button> <script src="popup.js"></script> </body> </html>
d) 在 chrome-extension/popup.js
中创建 popup.js 文件
document.addEventListener('DOMContentLoaded', function() { const signInButton = document.getElementById('signInButton'); const signOutButton = document.getElementById('signOutButton'); const userInfo = document.getElementById('userInfo'); function updateUI(user) { if (user) { userInfo.textContent = `Signed in as: ${user.email}`; signInButton.style.display = 'none'; signOutButton.style.display = 'block'; } else { userInfo.textContent = 'Not signed in'; signInButton.style.display = 'block'; signOutButton.style.display = 'none'; } } chrome.storage.local.get(['user'], function(result) { updateUI(result.user); }); signInButton.addEventListener('click', function() { chrome.runtime.sendMessage({action: 'signIn'}, function(response) { if (response.user) { updateUI(response.user); } }); }); signOutButton.addEventListener('click', function() { chrome.runtime.sendMessage({action: 'signOut'}, function() { updateUI(null); }); }); });
e) 在chrome-extension/background.js
中创建background.js文件
const OFFSCREEN_DOCUMENT_PATH = 'offscreen.html'; const FIREBASE_HOSTING_URL = 'https://your-project-id.web.app'; // Replace with your Firebase hosting URL let creatingOffscreenDocument; async function hasOffscreenDocument() { const matchedClients = await clients.matchAll(); return matchedClients.some((client) => client.url.endsWith(OFFSCREEN_DOCUMENT_PATH)); } async function setupOffscreenDocument() { if (await hasOffscreenDocument()) return; if (creatingOffscreenDocument) { await creatingOffscreenDocument; } else { creatingOffscreenDocument = chrome.offscreen.createDocument({ url: OFFSCREEN_DOCUMENT_PATH, reasons: [chrome.offscreen.Reason.DOM_SCRAPING], justification: 'Firebase Authentication' }); await creatingOffscreenDocument; creatingOffscreenDocument = null; } } async function getAuthFromOffscreen() { await setupOffscreenDocument(); return new Promise((resolve, reject) => { chrome.runtime.sendMessage({action: 'getAuth', target: 'offscreen'}, (response) => { if (chrome.runtime.lastError) { reject(chrome.runtime.lastError); } else { resolve(response); } }); }); } chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { if (message.action === 'signIn') { getAuthFromOffscreen() .then(user => { chrome.storage.local.set({user: user}, () => { sendResponse({user: user}); }); }) .catch(error => { console.error('Authentication error:', error); sendResponse({error: error.message}); }); return true; // Indicates we will send a response asynchronously } else if (message.action === 'signOut') { chrome.storage.local.remove('user', () => { sendResponse(); }); return true; } });
f) 在 chrome-extension/offscreen.html
中创建 offscreen.html 文件
<!DOCTYPE html> <html> <head> <title>Offscreen Document</title> </head> <body> <script src="offscreen.js"></script> </body> </html>
g) 在 _chrome-extension/offscreen.js 中创建一个 offscreen.js 文件
_
const FIREBASE_HOSTING_URL = 'https://your-project-id.web.app'; // Replace with your Firebase hosting URL const iframe = document.createElement('iframe'); iframe.src = FIREBASE_HOSTING_URL; document.body.appendChild(iframe); chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { if (message.action === 'getAuth' && message.target === 'offscreen') { function handleIframeMessage({data}) { try { const parsedData = JSON.parse(data); window.removeEventListener('message', handleIframeMessage); sendResponse(parsedData.user); } catch (e) { console.error('Error parsing iframe message:', e); } } window.addEventListener('message', handleIframeMessage); iframe.contentWindow.postMessage({initAuth: true}, FIREBASE_HOSTING_URL); return true; // Indicates we will send a response asynchronously } });
a) 在 Firebase 控制台中,转到“身份验证”>登录方法。
b) 启用 Google 作为登录提供商。
c) 将您的 Chrome 扩展程序 ID 添加到授权域列表:
格式为:chrome-extension://YOUR_EXTENSION_ID
作为解压的扩展程序加载后,您可以在 Chrome 的扩展程序管理页面中找到您的扩展程序 ID。
a) 打开 Google Chrome 并转到 chrome://extensions/。
b) 启用右上角的“开发者模式”。
c) 单击“加载解压”并选择您的 chrome 扩展目录。
d) 单击 Chrome 工具栏中的扩展程序图标以打开弹出窗口。
e) 单击“登录”按钮并测试身份验证流程。
如果您遇到 CORS 问题,请确保在 background.js 和 offscreen.js 中正确设置您的 Firebase 托管 URL。
确保您的 Chrome 扩展程序的 ID 已正确添加到 Firebase 的授权域。
检查弹出窗口、后台脚本和屏幕外文档中的控制台日志是否有任何错误消息。
您现在拥有一个 Chrome 扩展程序,它使用 Firebase 身份验证和屏幕外文档来处理登录过程。此设置允许安全身份验证,而无需直接在扩展代码中暴露敏感的 Firebase 配置详细信息。
请记住在发布扩展程序之前将占位符值(例如 YOUR_EXTENSION_ID、YOUR-CLIENT-ID、YOUR_PUBLIC_KEY 和 your-project-id)替换为您的实际值。
以上是使用 Firebase 的 Chrome 扩展程序中的 Google 身份验证的详细内容。更多信息请关注PHP中文网其他相关文章!