我创建了一个 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 存储中存储此扩展程序的密码之间有什么区别,也许需要一些混淆步骤以防止它被清楚地读取?
为了解决这个问题,我创建了一个端点来验证和记录用户使用自定义令牌。它的工作原理如下: