"Cannot parse context" 将 firebaseui-web 与 Google 主页一起使用时出错

"Cannot parse context" error using firebaseui-web with Google Home

我正在尝试设置 account linking for my Google Home action. To authenticate the user when they login to do the linking, I am using Firebase Auth and FirebaseUI-web with the Google Sign-In provider. The page and code-flow validates when using the Google OAUth2 Playground and when I test account linking using the Google Home emulator, both of which I've tested using desktop Chrome. But when I go to test with the Google Home device and app,它启动流程并显示登录按钮,让我 select 一个帐户,重定向回我的页面,然后生成错误:

当我将 Chrome 调试控制台连接到它时,控制台出现以下错误:

[  1.995s] [firebaseui] Internal error: {"error":{"errors":[{"domain":"global","reason":"invalid","message":"Cannot parse context"}],"code":400,"message":"Cannot parse context"}}

如果我查看网络日志,最后的 xhr POST returns 一个 400 错误。 (一些信息被删节了,因为我不知道发送的数据的敏感性。)

要求:


URL:https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyAssertion?key=[redacted]
Method:POST

请求headers:


Content-Type:application/json
Origin:https://redacted.example.com
Referer:https://redacted.example.com/auth?response_type=code&client_id=api-ai-test&redirect_uri=https://oauth-redirect.googleusercontent.com/r/redacted-project&scope=test1&state=redacted
User-Agent:Mozilla/5.0 (Linux; Android 6.0.1; A0001 Build/MHC19Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.91 Mobile Safari/537.36
X-Client-Version:Chrome/JsCore/3.6.5

Body:


{
  "postBody": "id_token=redacted&access_token=re.dacted&providerId=google.com",
  "requestUri": "https://redacted.example.com/auth?response_type=code&client_id=api-ai-test&redirect_uri=https://oauth-redirect.googleusercontent.com/r/redacted-project&scope=test1&state=redacted",
  "returnIdpCredential": true,
  "returnSecureToken":true
}

HTTP 响应代码为 400 body:


{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "invalid",
    "message": "Cannot parse context"
   }
  ],
  "code": 400,
  "message": "Cannot parse context"
 }
}

有什么方法可以让它正常工作吗?是什么导致了问题?

更新以更好地解释用户流程

了解 FirebaseUI 用于对登录 my OAuth2 服务的用户进行身份验证很重要。不获取OAuth信息直接提供给Home

所以流程是:

  1. 用户使用 "Hey Google, talk to bill pay by voice"
  2. 等触发器在主页上发起操作
  3. 由于用户尚未将他们的 Home 连接到 "bill pay by voice" 服务,Home 会提示用户转到 Google Home 应用程序和 link 这两个帐户。
  4. 那张卡片是这样显示的。
  5. 用户点击卡片,Chrome 自定义选项卡打开我的登录页面,让他们登录我的服务。这个页面是用 FirebaseUI 实现的,有一个按钮让他们使用他们的 Google 帐户登录我的服务。
  6. 如有必要,他们 select 一个帐户,登录,然后重定向回页面以继续。正是在这个时候出现了错误。
  7. 但是,如果它正常工作,该页面会向我的 back-end 服务发送登录信息。这将结束 FirebaseUI 的参与。此时,后端服务将联系 Firebase Auth 服务以获取帐户信息,为该帐户生成授权码,并让页面继续 OAuth2 流程并从我的服务向 Google 提供授权码。

请注意,虽然 (4) 发生在 Chrome 自定义选项卡中,但我还告诉它在 Chrome 本身中打开(通过选项卡中的菜单项),并且它继续显示相同的问题。

我不清楚步骤 (5) 中到底发生了什么。有一些对身份工具包服务的调用在失败并显示调用之前似乎有效。

当 OAuth 流程在由于 OAuth 状态参数不匹配而未启动它的设备上完成时,通常会抛出此错误。 firebaseui 与帐户链接不兼容。 您能否解释一下您的整个流程,以便我进一步理解并提供更准确的解释?

好的。我认为这就是正在发生的事情。 FirebaseUI signInWithCredential 用于使用 OAuth 令牌登录,调用下面的 verifyAssertion。它将 Google OAuth 访问令牌和 ID 令牌与 requestURI(当前 URL)一起传递到 Firebase Auth 后端。

问题是您正在尝试使用 FirebaseUI 构建您自己的 OAuth 提供程序。 OAuth 协议建议状态参数由第 3 方应用程序(google 家)提供,然后与授权代码一起返回给它。问题是当前 URL 中的这个状态参数被发送到 verifyAssertion(requestUri 字段)请求中的 Firebase Auth 后端,然后尝试检查它并注意到它无效(这并不意味着被 Firebase 使用在这种情况下是 Auth 后端),因此抛出错误 "Cannot parse context",当 OAuth 状态参数不匹配时抛出该错误。

要使其正常工作,托管您的登录 UI 的网页不应在查询字符串中包含状态参数。

目前,这里有一个解除屏蔽的选项:

  1. Google 主页触发帐户链接,使用所有预期参数(redirect_uri、范围、client_id、状态、response_type)重定向到您的网页。
  2. 将这些保存在 sessionStorage 中并重定向到另一个托管您的 FirebaseUI 的页面。
  3. 使用 sessionStorage 信息,呈现 firebaseUI 和所有其他 UI,当用户完成流程时,用户将返回到登录页面。
  4. 然后您可以发出授权代码,提取 sessionStorage 信息(redirect_uri,状态)并重定向到 redirect_uri,并附加状态和授权代码。

总而言之,您需要确保当用户在登录后被重定向回托管您的 firebaseui 的页面时,URL 查询字符串中没有状态参数可用。否则 Firebase Auth 后端将假定它是为它准备的。

测试以上内容,如果可行请告诉我。我会在下周就此问题回复您。

如果不清楚,请告诉我,如果需要,我可以进一步解释。