Firebase-tools: Firestore 模拟器 WebChannel 身份验证未兑现

创建于 2019-08-28  ·  3评论  ·  资料来源: firebase/firebase-tools

环境信息

火力基地工具: 7.30

平台: macOS 10.14.6

测试用例

我的目标是让经过身份验证的 Firestore 模拟器请求在浏览器中本地工作。 具体用例用于本地测试。 为了测试这种情况,我克隆了firebase/quickstart-nodejs 存储库,并向firestore-emulator/browser-quickstart示例添加了一个简单的模拟身份验证令牌,如https://github.com/firebase/firebase-tools/issues/ 中所述1001#issuecomment -523319483。

请参阅webchannel-auth-issue分支以获取演示该问题的最小测试用例(更改包含在 https://github.com/jkeys089/quickstart-nodejs/commit/a1456011525b0d40e5af14b38ca26898c6199151 中)。

重现步骤

正常运行firestore-emulator/browser-quickstart示例。

预期行为

示例项目应该可以正常工作(即允许用户在 textarea 中输入文本,将其存储在本地 firestore 模拟器中,然后看到文本成功显示在 textarea 上方)。

实际行为

在运行示例项目时,我们会在加载页面 ( Uncaught Error in onSnapshot: FirebaseError: ) 和尝试发布文本 ( Uncaught (in promise) FirebaseError: PERMISSION_DENIED: ) 时在浏览器开发控制台中看到多个错误。

emulator-suite firestore bug

最有用的评论

@jkeys089我奖励你 100 个互联网积分,因为你提供了一个非开源模拟器的补丁! 谢谢你把这说得很清楚。

@ryanpbrewster@IanWyszynski你怎么看?

所有3条评论

我实际上花了一些时间调试这个问题,我相信我已经发现了这个问题。 尽管Firestore 模拟器的源不可用,但我确实设法创建了一个补丁来修复此错误/允许经过身份验证的请求按预期运行:

--- com/google/cloud/datastore/emulator/firestore/webchannel/FirestoreV1WebChannelAdapter.java    2019-08-28 00:42:06.000000000 -0400
+++ FirestoreV1WebChannelAdapter.java    2019-08-27 23:34:54.000000000 -0400
@@ -190,7 +190,17 @@
          String url = channel.getHandshakeHeaders().getUrl();
          QueryStringDecoder decoder = new QueryStringDecoder(url);
          String db = (String)((List)Preconditions.checkNotNull((List)decoder.parameters().get("database"), "expected %s to have a 'database' query parameter", (Object)url)).get(0);
-         Context.current().withValue(FirestoreEmulatorMetadataKeys.DATABASE_REF.contextKey(), db).run(() -> {
+         String auth = null;
+         if (decoder.parameters().get("$httpHeaders") != null) {
+            for (String rawHeader : decoder.parameters().get("$httpHeaders").get(0).split("\r\n")) {
+               if (rawHeader.startsWith("Authorization:")) {
+                  auth = rawHeader.substring(14).trim();
+                  break;
+               }
+            }
+         }
+         Context.current().withValue(FirestoreEmulatorMetadataKeys.AUTHORIZATION.contextKey(), auth).withValue(
+            FirestoreEmulatorMetadataKeys.DATABASE_REF.contextKey(), db).run(() -> {
             Object handler;
             if (url.startsWith("/google.firestore.v1.Firestore/Write/")) {
                handler = new FirestoreV1WebChannelAdapter.FirestoreWriteHandler(this.router, channel);

@jkeys089我奖励你 100 个互联网积分,因为你提供了一个非开源模拟器的补丁! 谢谢你把这说得很清楚。

@ryanpbrewster@IanWyszynski你怎么看?

令人印象深刻的工作:)

就其价值而言,这与实际添加来处理这种情况的代码非常相似。 如果您升级到 Firestore 模拟器的 v1.8.1(随firebase-tools软件包的 v7.3.0 一起提供),这应该是固定的。

如果您遇到其他问题,请重新打开此问题,再次感谢您的报告! :咧嘴笑:

此页面是否有帮助?
0 / 5 - 0 等级