保持身份验证状态Firebase + Chrome扩展

时间:2019-04-22 21:41:31

标签: javascript html firebase google-chrome-extension firebase-authentication

我正在尝试在我的Chrome扩展程序中设置身份验证。我只是希望用户能够单击扩展程序图标,使用电子邮件+密码登录,然后能够使用扩展程序的不同组件。如果扩展程序弹出窗口已关闭,则无需再次登录。

我一直以非常有限的开发经验严格遵循文档hereherethe 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.htmlbackground.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,但无法理解它如何适合我的工作。

目前,我不知道下一步该怎么做。

1 个答案:

答案 0 :(得分:0)

我找到了解决我问题的方法。我链接到的问题中来自@cloop的答案是正确的,但是为了以后遇到这个问题的人们,我将以自己的方式进行解释。我希望这将对新手更友好,因为我自己不是开发人员。

请注意,这只是我获得MVP的解决方案,很有可能有更好的方法来解决这个问题。

首先,请勿使用Firebase UI库,因为该库与Chrome扩展程序不兼容。我将假定您已经阅读了Chrome Extension tutorialFirebase 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才能在脚本中对其进行初始化,例如参见脚本herepopup.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完全加载以查询身份验证状态后立即向后台脚本发送一条消息。后台脚本将向我们发送类型为responseloggedIn的{​​{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状态的更改。

我不会进一步介绍细节,但我希望这足以使像我这样的初学者脑袋绕开,并提出一个可行的原型。

简而言之:

  • 不要使用Firebase UI库
  • 在后台脚本中初始化Firebase
  • 扩展名是单页应用程序。使用Messaging API从后台脚本中获取当前身份验证状态或身份验证状态更改,以便能够决定要为用户提供服务的界面

如果有人发现此答案有任何问题,请不要犹豫。值得赞扬的是无数的人,他们足够善良,可以帮助我开发Discord,或者我发给我发疯的少数开发人员,使我走上正轨。

相关问题