在 chrome.local 存储中保留 firebase 会话以启用自动登录而不使用 indexedDB?(带有firebase登录的Chrome扩展程序)

N4T*_*4TT 5 google-chrome-extension firebase firebase-authentication

我正在使用内容脚本

我创建了一个 chrome 扩展,它可以在我无法控制的任意数量的域上运行,并且该扩展通过内容脚本使用Firebase登录。

我的问题是Firebase似乎通过使用indexedDB来保持状态,但这使得扩展容易受到恶意网站的攻击,通过读取indexedDB 状态来窃取用户会话(也许我在这里错了?)。

当扩展被激活时,我通过一个使用Firebase javacript sdk来获取数据和管理登录会话的内容脚本将一个微小的反应应用程序注入到 DOM 中。我希望用户的登录状态保持不变,这样他们就不必每次使用扩展程序时都登录(否则我想我可以将 Firebase 持久性设置为 NONE 以防止它使用indexedDB)。

我在想,如果我能以某种方式将会话(可能是refreshToken)保存在chrome存储区域中,然后在加载时读取它以重新初始化用户会话,那么会话更安全(不是很安全,但比如果我更安全使用indexedDB)。即使可以通过在 PC 上输入正确的文件夹来访问存储区域,但将数据存储在那里似乎更好,只有扩展程序才能以编程方式访问它。

到目前为止我尝试过的事情

手动方式

我曾尝试使用带有 apiKey 和刷新令牌的端点来获取新凭据(参考:如何使用 Firebase refreshToken 重新进行身份验证?),这工作正常。我还能够从执行后返回的用户对象中获取 refreshToken signInWithEmailAndPassword()

所以最后一块拼图是将这个刷新的登录状态通过管道传输到 Firebase sdk 中,以便能够使用 firebase sdk 功能,如更改侦听器等。但我还没有找到这样做的方法。有谁知道这是否可能?

内置方法

有一种方法叫signInAndRetrieveDataWithCredential我尝试使用。登录函数返回一个凭证对象,我试图将其传入 signInAndRetrieveDataWithCredential以恢复用户会话,但该方法返回一个错误,指出该对象无效。可能有很多东西不应该保留在凭证对象中,所以这不是首选方式,但作为最后的手段,我可​​以将其视为一种选择。但作为关于 Firebase 的一个更普遍的问题,有没有办法让用户保持登录状态并将其存储在 chrome.storage 之类的地方?

最糟糕的方式

在 chrome 存储中保留用户名/密码是可能的,并且可以为扩展程序提供在用户打开时登录的选项。这当然是解决问题的可怕方式,并不是真正的选择。但是我已经读到 chrome 密码管理器也存储相对不安全的密码,那么这与在 chrome 存储中存储此扩展程序的密码之间有什么区别,也许需要一些混淆步骤以防止它被清楚地读取?

**更新**

为了解决这个问题,我创建了一个端点来验证和记录用户使用自定义令牌。它的工作原理如下:

  1. 用户登录,将 refreshToken 存储在chrome.storage.sync 中
  2. 当用户第二次启动插件时,我从chrome storage.async 中获取令牌
  3. 将令牌发布到我创建的Firebase 函数,该函数使用上面“手动方式”部分中描述的刷新令牌的方法。
  4. 如果我在从Firebase 函数调用身份验证端点时得到肯定的结果,我认为令牌有效并使用返回的数据中的 userId 创建发送回用户的自定义令牌
    1. 使用此自定义令牌通过调用登录用户 firebase.auth().signInWithCustomToken(token)

自定义令牌链接:https : //firebase.google.com/docs/auth/admin/create-custom-tokens#create_custom_tokens_using_the_firebase_admin_sdk

但是上面的问题仍然存在:

  1. 是否可以在 firebase persist 上下文之外存储用户会话,然后在用户回来时使用此会话数据再次“激活”用户会话?像signInWithRefreshToken什么?
  2. 是否有一种内置方法可以让用户登录并将其存储在 chrome.storage 之类的地方?(答案似乎是否定的)。
  3. 有没有办法将混淆的用户登录信息存储在 chrome.storage.sync 中,可以认为足够安全?该信息在页面加载时使用,并在凭据不再有效或用户注销时删除。

**第二次更新**

当我在Firebase上托管的测试站点上运行以下脚本并且扩展程序安装在本地而不是通过 chrome 网上商店时,我得到了持久的 firebase 会话,包括刷新令牌

        const request = window.indexedDB.open("firebaseLocalStorageDb", 1);
        request.onerror = function (event) {
            console.err("error fetching data", event);
        };
        request.onsuccess = function (dbEvent) {
            const db = request.result;
            const transaction = db.transaction(["firebaseLocalStorage"]);
            console.log({transaction});
            const objectStore = transaction.objectStore("firebaseLocalStorage");
            if ('getAll' in objectStore) {
                objectStore.getAll().onsuccess = function (getAllEvent) {
                    console.log(event.target.result);
                };
            }
        };
Run Code Online (Sandbox Code Playgroud)

此外,当我使用调试器窗口检查 indexeddb 时,扩展的 indexeddb 将安全源设置为它加载的页面。

chrome 调试器窗口中安全源的屏幕截图