使用 Firebase 的 Chrome 擴充功能中的 Google 驗證
我們寫本指南是因為 Google 的官方指南缺少一些重要步驟,我們在下面連結了:
在 Chrome 擴充功能中使用 Firebase 進行驗證
這適用於任何作業系統。出於本指南的目的,我們將使用 Mac OS
先決條件
- Google瀏覽器
- Google 帳號
- Chrome 網路應用商店開發者帳戶(一次性費用 5 美元)
- 已安裝 Node.js 和 npm
第 1 步:建立專案結構
a) 為您的專案建立一個新目錄:
mkdir firebase-chrome-auth cd firebase-chrome-auth
b) 建立兩個子目錄:
mkdir chrome-extension mkdir firebase-project
第 2 步:設定 Firebase 項目
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 擴充功能需要它。
第 3 步:設定 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 } });
步驟 4:設定 Firebase 身份驗證
a) 在 Firebase 控制台中,前往「驗證」>登入方法。
b) 啟用 Google 作為登入提供者。
c) 將您的 Chrome 擴充功能 ID 新增至授權網域清單:
格式為:chrome-extension://YOUR_EXTENSION_ID
作為解壓縮的擴充功能載入後,您可以在 Chrome 的擴充功能管理頁面中找到您的擴充功能 ID。
第 5 步:載入並測試擴展
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中文網其他相關文章!

熱AI工具

Undress AI Tool
免費脫衣圖片

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

JavaScript中的日期和時間處理需注意以下幾點:1.創建Date對像有多種方式,推薦使用ISO格式字符串以保證兼容性;2.獲取和設置時間信息可用get和set方法,注意月份從0開始;3.手動格式化日期需拼接字符串,也可使用第三方庫;4.處理時區問題建議使用支持時區的庫,如Luxon。掌握這些要點能有效避免常見錯誤。

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

事件捕獲和冒泡是DOM中事件傳播的兩個階段,捕獲是從頂層向下到目標元素,冒泡是從目標元素向上傳播到頂層。 1.事件捕獲通過addEventListener的useCapture參數設為true實現;2.事件冒泡是默認行為,useCapture設為false或省略;3.可使用event.stopPropagation()阻止事件傳播;4.冒泡支持事件委託,提高動態內容處理效率;5.捕獲可用於提前攔截事件,如日誌記錄或錯誤處理。了解這兩個階段有助於精確控制JavaScript響應用戶操作的時機和方式。

如果JavaScript應用加載慢、性能差,問題往往出在payload太大,解決方法包括:1.使用代碼拆分(CodeSplitting),通過React.lazy()或構建工具將大bundle拆分為多個小文件,按需加載以減少首次下載量;2.移除未使用的代碼(TreeShaking),利用ES6模塊機制清除“死代碼”,確保引入的庫支持該特性;3.壓縮和合併資源文件,啟用Gzip/Brotli和Terser壓縮JS,合理合併文件並優化靜態資源;4.替換重型依賴,選用輕量級庫如day.js、fetch

ES模塊和CommonJS的主要區別在於加載方式和使用場景。 1.CommonJS是同步加載,適用於Node.js服務器端環境;2.ES模塊是異步加載,適用於瀏覽器等網絡環境;3.語法上,ES模塊使用import/export,且必須位於頂層作用域,而CommonJS使用require/module.exports,可在運行時動態調用;4.CommonJS廣泛用於舊版Node.js及依賴它的庫如Express,ES模塊則適用於現代前端框架和Node.jsv14 ;5.雖然可混合使用,但容易引發問題

在Node.js中發起HTTP請求有三種常用方式:使用內置模塊、axios和node-fetch。 1.使用內置的http/https模塊無需依賴,適合基礎場景,但需手動處理數據拼接和錯誤監聽,例如用https.get()獲取數據或通過.write()發送POST請求;2.axios是基於Promise的第三方庫,語法簡潔且功能強大,支持async/await、自動JSON轉換、攔截器等,推薦用於簡化異步請求操作;3.node-fetch提供類似瀏覽器fetch的風格,基於Promise且語法簡單

要寫出乾淨、可維護的JavaScript代碼,應遵循以下四點:1.使用清晰一致的命名規範,變量名用名詞如count,函數名用動詞開頭如fetchData(),類名用PascalCase如UserProfile;2.避免過長函數和副作用,每個函數只做一件事,如將更新用戶信息拆分為formatUser、saveUser和renderUser;3.合理使用模塊化和組件化,如在React中將頁面拆分為UserProfile、UserStats等小組件;4.寫註釋和文檔時點到為止,重點說明關鍵邏輯、算法選

var、let和const的區別在於作用域、提升和重複聲明。 1.var是函數作用域,存在變量提升,允許重複聲明;2.let是塊級作用域,存在暫時性死區,不允許重複聲明;3.const也是塊級作用域,必須立即賦值,不可重新賦值,但可修改引用類型的內部值。優先使用const,需改變變量時用let,避免使用var。
