我正在尝试在我的Chrome扩展程序中设置身份验证。我只是希望用户能够单击扩展程序图标,使用电子邮件+密码登录,然后能够使用扩展程序的不同组件。如果扩展程序弹出窗口已关闭,则无需再次登录。
我一直以非常有限的开发经验严格遵循文档here,here和the Chrome Extension specific documentation here。
这是我的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
脚本询问this stackoverflow question的答案,但无济于事。
如果我没有完全迷路,我想我有一个为什么会这样的想法。如果我没有记错的话,浏览器操作弹出窗口将覆盖后台页面/脚本的操作。但是我不确定应该修改什么。我也看过this about authenticating Firebase with Chrome Extensions,但无法理解它如何适合我的工作。
目前,我不知道下一步该怎么做。
答案 0 :(得分:0)
我找到了解决我问题的方法。我链接到的问题中来自@cloop的答案是正确的,但是为了以后遇到这个问题的人们,我将以自己的方式进行解释。我希望这将对新手更友好,因为我自己不是开发人员。
请注意,这只是我获得MVP的解决方案,很有可能有更好的方法来解决这个问题。
首先,请勿使用Firebase UI库,因为该库与Chrome扩展程序不兼容。我将假定您已经阅读了Chrome Extension tutorial和Firebase Authentication文档的基础知识。
现在,我们必须舍弃到目前为止的所有内容,并以空扩展名开始。我们将为此设置电子邮件+密码验证。
首先,我们创建清单:
{
"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才能在脚本中对其进行初始化,例如参见脚本here。 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
的{{1}}对象,从而使我们可以决定为弹出窗口加载哪种接口。
现在我们看一下后台脚本。
首先,您应该初始化Firebase。
loggedOut
现在,我们需要添加一个消息侦听器。请注意,这会侦听来自 any Chrome环境(标签,窗口,弹出脚本等)的 any 消息,因此我们必须确保我们对正确的类型信息。这就是为什么我在弹出脚本消息创建中使用var config = {
/*Your config parameters from the Firebase console*/
};
firebase.initializeApp(config);
的原因。我所有的消息都至少具有{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
};
});
的消息发送到后台脚本,然后,如果登录成功,则后台脚本应对弹出脚本做出响应,允许我们用扩展程序的UI替换loginAttempt
内容。在这里,我们看到扩展实际上是一个单页应用程序。
我必须在后台脚本中使用方法#container
,如果我没有记错的话,它基本上是一个事件侦听器,如果它可以检测到auth状态的更改。
我不会进一步介绍细节,但我希望这足以使像我这样的初学者脑袋绕开,并提出一个可行的原型。
简而言之:
如果有人发现此答案有任何问题,请不要犹豫。值得赞扬的是无数的人,他们足够善良,可以帮助我开发Discord,或者我发给我发疯的少数开发人员,使我走上正轨。