我们编写本指南是因为 Google 的官方指南缺少一些重要步骤,我们在下面链接了:
在 Chrome 扩展程序中使用 Firebase 进行身份验证
这适用于任何操作系统。出于本指南的目的,我们将使用 Mac OS
先决条件
- 谷歌浏览器
- 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 文件
<title>Firebase Auth for Chrome Extension</title> <h1 id="Firebase-Auth-for-Chrome-Extension">Firebase Auth for Chrome Extension</h1> <script type="module" src="signInWithPopup.js"></script>
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-----" } </all_urls>
c) 在 chrome-extension/popup.html
中创建 popup.html 文件
<title>Firebase Auth Extension</title> <h1 id="Firebase-Auth-Extension">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>
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 文件
<title>Offscreen Document</title> <script src="offscreen.js"></script>
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中文网其他相关文章!

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

Atom编辑器mac版下载
最流行的的开源编辑器

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

禅工作室 13.0.1
功能强大的PHP集成开发环境

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

记事本++7.3.1
好用且免费的代码编辑器