[英]Persist auth state Firebase + Chrome Extension
我正在嘗試在Chrome擴展程序中設置身份驗證。 我只是希望用戶能夠單擊擴展程序圖標,使用電子郵件+密碼登錄,然后能夠使用擴展程序的不同組件。 如果擴展彈出窗口關閉,則不必再次登錄。
我的開發經驗非常有限,因此我一直嚴格遵守此處的文檔和此處 的Chrome Extension特定文檔 。
這是我的manifest.json
。
{
"name": "Extension",
"version": "0.1",
"description": "",
"permissions": [
"tabs",
"activeTab",
"storage"
],
"content_security_policy": "script-src 'self' https://www.gstatic.com/ https://*.firebaseio.com https://*.firebase.com https://www.googleapis.com; object-src 'self'",
"background": {
"page":"background.html",
"persistent": true
},
"browser_action": {
"default_popup": "popup.html",
"default_icon": {}
},
"manifest_version": 2
}
我的background.html
和background.js
與我上面鏈接到的最后一個示例嚴格相同,只是我當然用自己的Firebase配置代替了。
我的popup.html
是:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<script src="https://www.gstatic.com/firebasejs/5.10.0/firebase.js"></script>
<script src="firebase/initialize.js" charset="utf-8"></script>
<script src="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/3.5.2/firebaseui.css"/>
<link type="text/css" rel="stylesheet" href="styles/popup.css" />
</head>
<body>
<h1>Extension</h1>
<div id="firebaseui-auth-container"></div>
<!-- Firebase App (the core Firebase SDK) is always required and must be listed first -->
<script src="src/popup.js"></script>
</body>
</html>
其中initialize.js
只是Firebase初始化腳本,而我的popup.js
是:
//Initizalier FirebaseUI instance
var ui = new firebaseui.auth.AuthUI(firebase.auth());
//Define sign-in methods
var uiConfig = {
callbacks: {
//Callbacl if sign up successful
signInSuccessWithAuthResult: function(authResult) {
// User successfully signed in.
// Return type determines whether we continue the redirect automatically
// or whether we leave that to developer to handle.
//Script to replace popup content with my Extension UI
return false;
},
},
signInOptions: [
{
provider: firebase.auth.EmailAuthProvider.PROVIDER_ID,
requireDisplayName: false
}
],
};
//Initialize UI
ui.start('#firebaseui-auth-container', uiConfig);
使用此功能,我可以說每次單擊擴展圖標時登錄均有效,但是如果關閉並重新打開彈出窗口,則必須再次登錄。 我幾乎一直在問這個問題。 我也嘗試向我的background.js
腳本詢問此stackoverflow問題的答案,但無濟於事。
如果我沒有完全迷路,我想我就知道為什么會這樣。 如果我沒有記錯的話,瀏覽器操作彈出窗口將覆蓋后台頁面/腳本的操作。 但是我不確定應該修改什么。 我也查看了有關使用Chrome Extensions對Firebase進行身份驗證的內容,但是我無法理解它如何適合我的工作。
在這一點上,我不知道下一步該怎么做。
我已經找到解決問題的辦法。 我鏈接到的問題中來自@cloop的答案是正確的,但是為了以后遇到這個問題的人們,我將以自己的方式進行解釋。 我希望這將對新手更友好,因為我自己不是開發人員。
請注意,這僅僅是我擁有MVP的解決方案,很可能有更好的方法來解決這個問題。
首先, 請勿使用Firebase用戶界面庫,因為它與Chrome擴展程序不兼容。 我將假定您已經閱讀了Chrome擴展程序教程以及Firebase身份驗證文檔的基礎知識。
現在,我們必須舍棄到目前為止的所有內容,並以空擴展名開始。 我們將為此設置電子郵件+密碼驗證。
首先,我們創建清單:
{
"name": "Test extension",
"version": "0.1",
"description": "An extension to test Firebase auth",
"permissions": [/*Insert necessary permissions*/],
"content_security_policy": "script-src 'self' https://www.gstatic.com/ https://*.firebaseio.com https://*.firebase.com https://www.googleapis.com; object-src 'self'",
"background": {
"page":"background.html",
"persistent": true
},
"browser_action": {
"default_popup": "popup.html",
},
"manifest_version": 2
}
background.html
是鏈接到background.js
腳本的背景頁面。 這是因為我們必須先在頁面的<head>
中加載firebase,然后才能在腳本中對其進行初始化,例如,請參見此處的腳本。 popup.html
將是我們根據身份驗證狀態動態加載的頁面。 它鏈接到腳本popup.js
,僅包含div元素#container
。 我們將立即在該彈出窗口中添加一個事件偵聽器,以使用Messaging API將消息發送到后台腳本。
window.addEventListener('DOMContentLoaded', (_event) => {
console.log("DOM loaded and parsed");
//Send a message to background script informing that the page is loaded
chrome.runtime.sendMessage({type: "popupLoad"}, function (response) {
if (response.type == "loggedIn") {
let htmlString = /*Your extension UI's HTML*/;
document.querySelector("#container").innerHTML(htmlString);
} else if (response.type == "loggedOut") {
let htmlString = /*Log in form HTML*/
document.querySelector("#container").innerHTML(htmlString);
};
});
因此,我們在這里所做的就是在popup.html
的DOM完全加載以查詢身份驗證狀態后立即向后台腳本發送一條消息。 背景腳本將發送給我們一個response
類型的對象loggedIn
或loggedOut
,使我們能夠決定我們應該加載哪些接口,我們的彈出。
現在我們來看一下后台腳本。
首先,您應該初始化Firebase。
var config = {
/*Your config parameters from the Firebase console*/
};
firebase.initializeApp(config);
現在我們需要添加一個消息監聽器。 請注意,這將偵聽來自任何 Chrome環境的任何消息(標簽,窗口,彈出腳本等),因此我們必須確保對正確的消息類型進行處理。 這就是為什么我在彈出腳本消息創建中使用{type: "popupLoad"}
的原因。 我所有的消息至少都有一個type
屬性。
chrome.runtime.onMessage.addListener(
function(message, _sender, _sendResponse) {
if (message.type == "popupLoad") {
//Get current authentication state and tell popup
let user = firebase.auth().currentUser;
if (user) {
sendResponse({type: "loggedIn"});
} else {
sendResponse({type: "loggedOut"});
};
} else if (message.type == "other") {
//handle other types of messages
};
});
到目前為止,我們已經完成的工作是,只要用戶單擊擴展圖標,我們就可以根據身份驗證狀態決定彈出窗口的界面。 當然,如果用戶已注銷,他們將看到我們的登錄/注冊表格。 此表單的按鈕應具有一個事件偵聽器,該事件偵聽器將消息(例如, loginAttempt
類型)發送到后台腳本,然后,如果登錄成功,則后台腳本應對彈出腳本做出響應,這使我們可以替換#container
內容和擴展程序的UI。 在這里,我們看到擴展實際上是一個單頁應用程序。
我必須在后台腳本中使用方法firebase.auth().onAuthStateChanged()
,如果我沒有記錯的話,它可以檢測到身份驗證狀態的變化,這基本上是一個事件偵聽器。
我將不進一步介紹細節,但我希望這足以使像我這樣的初學者能夠全神貫注於此,並提出一個可行的原型。
簡而言之:
如果有人發現此答案有任何問題,請不要猶豫。 值得稱贊的是無數的人,他們足夠善良,可以幫助我開發Discord,或者我發給我發瘋的少數開發人員,使我走上正確的道路。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.