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

Exp*_*111 5 html javascript google-chrome-extension firebase firebase-authentication

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

我一直严格遵循此处的文档,此处以及此处的 Chrome 扩展特定文档,但我的开发经验非常有限。

这是我的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
}

Run Code Online (Sandbox Code Playgroud)

我的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>
Run Code Online (Sandbox Code Playgroud)

initialize.jsFirebase 初始化脚本在哪里,我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);
Run Code Online (Sandbox Code Playgroud)

使用这个,我可以说每次我点击扩展图标时登录都有效,但是如果我关闭并重新打开弹出窗口,我必须再次登录。我几乎到处都在问这个问题。我还尝试向我的脚本询问这个 stackoverflow 问题的答案,background.js但无济于事。

如果我没有完全迷失,我想我知道为什么会这样。如果我没记错的话,浏览器操作弹出窗口会覆盖背景页面/脚本正在执行的操作。但是我不确定我应该修改什么。我还查看了有关使用 Chrome 扩展程序对 Firebase 进行身份验证的相关内容,但我无法理解它如何适合我的工作。

在这一点上,我不知道接下来要做什么。

Exp*_*111 7

我已经找到了解决我的问题的方法。@cloop 在我链接到的问题中的答案是正确的,但为了稍后会遇到这个问题的人,我将用我自己的方式进行解释。我希望它对初学者更友好,因为我自己不是开发人员。

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

首先,不要使用Firebase UI库,因为它与 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
}
Run Code Online (Sandbox Code Playgroud)

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);
       };
  });
Run Code Online (Sandbox Code Playgroud)

所以我们在这里所做的是在我们的 DOMpopup.html完全加载后立即向后台脚本发送消息以查询身份验证状态。后台脚本将向我们发送一个response类型为loggedInor的对象loggedOut,允许我们决定应该为弹出窗口加载哪个界面。

现在我们看看后台脚本。

首先,您应该初始化 Firebase。

var config = {
    /*Your config parameters from the Firebase console*/
  };
firebase.initializeApp(config);
Run Code Online (Sandbox Code Playgroud)

现在我们需要添加一个消息监听器。请注意,这将侦听来自任何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
      };
    });
Run Code Online (Sandbox Code Playgroud)

到目前为止我们所做的是,只要用户点击扩展图标,我们就可以根据身份验证状态决定弹出窗口的界面应该是什么。当然,如果用户退出,他们会看到我们的登录/注册表格。这个表单的按钮应该有一个事件监听器,它向loginAttempt后台脚本发送一条消息(例如类型),然后如果登录成功,后台脚本应该给弹出脚本一个响应,这允许我们替换#container内容与我们的扩展程序的 UI。在这里我们看到扩展实际上是一个单页面应用程序。

我必须firebase.auth().onAuthStateChanged()在后台脚本中使用该方法 ,如果我没记错的话,它基本上是一个事件侦听器,如果它检测到身份验证状态的变化。

我不会详细介绍,但我希望这足以让像我这样的初学者围绕这一点思考并提出一个工作原型。

简而言之:

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

如果有人注意到此答案有任何问题,请不要犹豫。一些功劳要归功于在 dev Discord 上帮助我的许多人,或者我突然通过电子邮件发送给我并让我走上正轨的少数开发人员。