首頁 web前端 js教程 使用 Firebase 的 Chrome 擴充功能中的 Google 驗證

使用 Firebase 的 Chrome 擴充功能中的 Google 驗證

Sep 06, 2024 am 06:41 AM

Google Authentication in a Chrome Extension with Firebase

我們寫本指南是因為 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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

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

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

如何在JS中與日期和時間合作? 如何在JS中與日期和時間合作? Jul 01, 2025 am 01:27 AM

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

為什麼要將標籤放在的底部? 為什麼要將標籤放在的底部? Jul 02, 2025 am 01:22 AM

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

什麼是在DOM中冒泡和捕獲的事件? 什麼是在DOM中冒泡和捕獲的事件? Jul 02, 2025 am 01:19 AM

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

如何減少JavaScript應用程序的有效載荷大小? 如何減少JavaScript應用程序的有效載荷大小? Jun 26, 2025 am 12:54 AM

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

JavaScript模塊上的確定JS綜述:ES模塊與COMPORJS JavaScript模塊上的確定JS綜述:ES模塊與COMPORJS Jul 02, 2025 am 01:28 AM

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請求? 如何在node.js中提出HTTP請求? Jul 13, 2025 am 02:18 AM

在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代碼的最佳實踐是什麼? 編寫清潔和可維護的JavaScript代碼的最佳實踐是什麼? Jun 23, 2025 am 12:35 AM

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

var vs Let vs const:快速JS綜述解釋器 var vs Let vs const:快速JS綜述解釋器 Jul 02, 2025 am 01:18 AM

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

See all articles