2

我正在尝试为我的 Google Home 操作设置帐户链接。为了在用户登录进行链接时对用户进行身份验证,我将 Firebase Auth 和FirebaseUI-web与 Google 登录提供程序一起使用。页面和代码流在使用 Google OAUth2 Playground 和我使用 Google Home emulator 测试帐户链接时进行验证,这两者我都使用桌面 Chrome 进行了测试。但是当我使用Google Home 设备和应用程序进行测试时,它会启动流程并显示登录按钮,让我选择一个帐户,重定向回我的页面,然后生成错误:

发生内部错误。 解雇

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

[ 1.995s] [firebaseui] 内部错误:{"error":{"errors":[{"domain":"global","re​​ason":"invalid","message":"Cannot parse context"}], "code":400,"message":"无法解析上下文"}}

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

要求:


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

请求标头:


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

身体:


{
  "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,正文为:


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

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

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

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

所以流程是:

  1. 用户使用诸​​如“Hey Google,通过语音通话支付账单”之类的触发器在 Home 上启动操作
  2. 由于用户尚未将其 Home 连接到“语音支付”服务,Home 会提示用户前往 Google Home 应用并关联两个帐户。
  3. 那张卡是这样出现的。在此处输入图像描述
  4. 用户点击卡片,Chrome 自定义选项卡会打开我的登录页面,让他们登录我的服务。这个页面是用 FirebaseUI 实现的,并且有一个按钮让他们使用他们的 Google 帐户登录我的服务。
  5. 如有必要,他们会选择一个帐户,登录,然后被重定向回页面以继续。正是在这一点上出现了错误。
  6. 但是,如果它正常工作,该页面将向我的后端服务发送登录信息。这将结束 FirebaseUI 的参与。此时,后端服务将联系 Firebase 身份验证服务以获取帐户信息,为该帐户生成授权代码,并让页面继续 OAuth2 流程并将我的服务中的授权代码提供给 Google。

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

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

4

2 回答 2

2

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

问题是您正在尝试使用 FirebaseUI 构建自己的 OAuth 提供程序。OAuth 协议建议 state 参数由 3rd 方应用程序(google home)提供,然后与 Auth 代码一起返回给它。问题是您当前 URL 中的这个状态参数被发送到 verifyAssertion(requestUri 字段)请求中的 Firebase Auth 后端,然后尝试检查它并注意到它是无效的(这并不意味着 Firebase Auth 后端在此使用case),从而引发错误“无法解析上下文”,当存在 OAuth 状态参数不匹配时会引发该错误。

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

现在,这里有一个解除阻止您的选项:

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

总结是您需要确保当用户在登录后被重定向回托管您的 firebaseui 的页面时,URL 查询字符串中没有可用的 state 参数。否则,Firebase 身份验证后端将假定它是为此而生的。

测试上述内容并让我知道这是否有效。我会在下周就这个问题回复你。

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

于 2017-01-28T09:42:32.643 回答
0

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

于 2017-01-27T02:12:24.100 回答