2

我正在尝试构建一个 Rails 应用程序作为自定义 Google Actions 的后端。粗略的用户流程将是我的应用程序的用户通过“与my_action交谈”调用我的自定义操作,这将要求他们登录。从那里,我可以继续从他们的谷歌帐户中提取用户信息。我现在面临的问题是在帐户链接过程中。

所以,目前的流程是这样的:

'与my_action 交谈' >> 用户提示查看 Google Home 应用以链接帐户 >> 用户点击链接以链接其帐户 >> 重定向到他们选择用户帐户/使用 google 帐户登录的页面 >> '来自的错误响应身份验证代码交换中的 IdP '。我已经搜索了有关此错误消息的高低,但我只能找到有关此特定消息的一个。

(抱歉,由于缺乏声誉,我无法发布屏幕截图!但基本上错误屏幕只是*Bad response from IdP in Auth Code Exchange*一个链接,*Re-run linking flow*但仍然无法正常工作。)

目前,我正在使用 gem'omniauth-google-oauth2'通过 OmniAuth 中的 OAuth2 向 Google 进行身份验证。我不太确定omniauth 部分,但是oauth auth 代码交换应该按照here中的描述进行。

我也在使用 gem google_assistant,特别是 assistant-api-v2 分支。这个 gem 有一段时间没有更新了,可能没有被广泛使用/测试,所以这可能是一个潜在的原因。我的服务器托管在 heroku 上,我使用 DialogFlow 作为实现工具。在 DialogFlow 中,我已经为我的应用启用了 webhook /myapp/google_assistant,并且我已经勾选了Sign-In Required复选框。

至于我在 Google 控制面板上的操作中的帐户链接设置,我已经

  1. 将链接类型设置为仅 Oauth,并将授权类型设置为隐式。
  2. 将客户端 ID 设置为我的 oauth2 客户端 ID
  3. 授权 URL 为“ my-app.com/users/auth/google_oauth2 ”(不需要令牌 URL)
  4. 将范围设置为 gmail
  5. 设置测试信息为“用户名:test@email.com,密码:密码”。我还不知道该字段的正确格式是什么。

在链接过程中,我的 Heroku web-app 服务器上的日志如下:

2018-07-05T10:44:16.955840 #4]  INFO -- : [a5b63d61-d97d-4b04-a10b-b3fee18c1c7d] Started GET "/users/auth/google_oauth2?response_type=token&client_id=*my_client_id*&redirect_uri=https://oauth-redirect.googleusercontent.com/r/*my_project_id*&scope=https://mail.google.com/&state=AA7-RQxyASRZMH3DU8v1lXOx08dXZdlDa_8qIqoQfcdSdbT2ltPpyO4JVYGo7SZWmCLgu2oq1aPnojP_ygDQQgjH-3fz7EFopdKVl1WqABA_uhSfwxGqN5ywmLXWE-Y74AFMTs4sEVkG_ctUxCz7oMXDumdPELRjHlhO0VRhcJXQFhCZ_2OOrEDKkST-pPLy_cD4T2Pptni9JQj8QUeXYkklg1I-836q4zqt6vOA9mCEEFqS_h0hwaVizBypk8joO85dOibe8w4OYlp4BHDegSQ_97oPeHJu_7TSJg9M2fAyZqww0XDNjwQAFCwFR1Z0fZ3b4RySlG5Uy_yLr_F5wLbMLvLa0mX63mwuf3hOUX4zoCpBoMnBcLi7hFUiaPj1wpTBhmrAZ05Oq6jKRcOqC-FX6yERPl5tQvNdsGdjH63mc-4J3tDL0tUzvvkYm6p0CjuOho4GiQwA1XZGvHZmOcKPLA6CKr26THAXmPVJSQmiIH1CSAuAypguuiNy0yhmMKgTH_WH5M8banpYYob-Yv2jVqu2H5f2RjF0i_XApCcHUj6VoNEg0cFYiMYaiIKJRH20-HpymW3IgOEd_2TjPg5yKEbYN5bN7C-zILVLC_1qyofyze0ag0lxgvsx3kvbAEI1MLpVAF0EACZeHJujzb8YM0vmOB8FuQLOeSanyZ8zrwrWXRzu9hSBQ4eHegsSneb5CugcQkt09uSnQhOTGGwOi0TVk_f6Sw" for *my_ip* at 2018-07-05 10:44:16 +0000

2018-07-05T10:44:16.956747+00:00 app[web.1]: I, [2018-07-05T10:44:16.956679 #4]  INFO -- omniauth: (google_oauth2) Request phase initiated.

2018-07-05T10:44:17.015111+00:00 heroku[router]: at=info method=GET path="/users/auth/google_oauth2?response_type=token&client_id=*my-client-id*&redirect_uri=https://oauth-redirect.googleusercontent.com/r/my-project-id&scope=https://mail.google.com/&state=AA7-RQxyASRZMH3DU8v1lXOx08dXZdlDa_8qIqoQfcdSdbT2ltPpyO4JVYGo7SZWmCLgu2oq1aPnojP_ygDQQgjH-3fz7EFopdKVl1WqABA_uhSfwxGqN5ywmLXWE-Y74AFMTs4sEVkG_ctUxCz7oMXDumdPELRjHlhO0VRhcJXQFhCZ_2OOrEDKkST-pPLy_cD4T2Pptni9JQj8QUeXYkklg1I-836q4zqt6vOA9mCEEFqS_h0hwaVizBypk8joO85dOibe8w4OYlp4BHDegSQ_97oPeHJu_7TSJg9M2fAyZqww0XDNjwQAFCwFR1Z0fZ3b4RySlG5Uy_yLr_F5wLbMLvLa0mX63mwuf3hOUX4zoCpBoMnBcLi7hFUiaPj1wpTBhmrAZ05Oq6jKRcOqC-FX6yERPl5tQvNdsGdjH63mc-4J3tDL0tUzvvkYm6p0CjuOho4GiQwA1XZGvHZmOcKPLA6CKr26THAXmPVJSQmiIH1CSAuAypguuiNy0yhmMKgTH_WH5M8banpYYob-Yv2jVqu2H5f2RjF0i_XApCcHUj6VoNEg0cFYiMYaiIKJRH20-HpymW3IgOEd_2TjPg5yKEbYN5bN7C-zILVLC_1qyofyze0ag0lxgvsx3kvbAEI1MLpVAF0EACZeHJujzb8YM0vmOB8FuQLOeSanyZ8zrwrWXRzu9hSBQ4eHegsSneb5CugcQkt09uSnQhOTGGwOi0TVk_f6Sw" host=*my-web-app* request_id=a5b63d61-d97d-4b04-a10b-b3fee18c1c7d fwd="*my-ip*" dyno=web.1 connect=0ms service=63ms status=302 bytes=5935 protocol=https

至于进程的重定向链,我不知道如何完全保存网络日志,但是使用Chrome扩展,登录谷歌帐户时的重定向链,导致错误响应错误是:

Status Code URL IP  Page Type   Redirect Type   Redirect URL    
302 https://oauth-redirect.googleusercontent.com/r/*my-project-id*?state=AA7-RQyd1KsD63DBoQF_-NfYijzGvptfXTEj8D3AwQzW_ByUe8K0UnLZVuQjE6y8txJMcabFTC4fQhxHqqpTv28_e3dDuLBpYaGKqo_urwHkswmf1pAV2da7nPoVb-n1DHe1P-xU-jzU5c8vlyWCXJPpMDZyR7K0AQ7qdDCQRtr9oPpDymPyYknGIrQB6rI9VRSFinsGhZTnno2AvtOJCkTZfe3abYSdzjB-Am3PI9p-oAwh0f6mBzUGDYCMIB-traI_INV9fSa8tS9K363pBKUBQ-YgKI5nKI8Uqbz5UduNDwB99eQSUaEZu48vabVTwGjsLUczbkA46-u-AKAV65iwTPE6e-zRI11LRgfw4uObam8S3xvL3ok9pESzwGpMlBmEO0goyg9xJa2ULatLOy2PGRcMbWcuhyp84ttzedmiD2gdidVxHafEwgSpSEqad6YLWvCtV4XGbHxyuFZXF8rjFiDUK__KaJ2G-cbzyiXaVQ-YOh80NM8QQmAIPvys-2BTteP_G-1xjRZFpgJO6-dnZw2jelcF8KkITIGTNMuLejrcCyADjusaNOMrHMkASXohnq5p0lpkjPIcEZryghziPu3soPJ8A9jj8K9Ka-CWNosv9aBAnpN4eKYlOBEVljc6W824XPYgYMW62cBHlTlqV8RMNpo_5h6LRf2UdmY2T85xk3Iuz1_1Lr8jeu-UYZILPP2sc7HrjP7eFp70qgMCUQEk_JwsyQ&code=4/AAC6qctB8IxI0ijzYibSubvzae-yNgNcVOtUrbnhORSMNRxQXi2DeZE9wqn6lLqOLkb0NYeYRU15IH8H6qP9CcY# 172.217.160.1   server_redirect temporary   https://gala-demo.appspot.com/app#redirect_state=AA7-RQxBXe_JzFx7iXtcObVa7AJ4qPiiLY_XHrtgX861Z1TlUiOLFM3ymhzxqHWCONLFXjOJQkhNyCsH35cylVBrKtyLDaE-4J7wJ-P9PS3-JEPVeaoRnm7uo4ncLPW5EMxR--onGLFNZydFbqNKhdhWTox3FkUuv2lNZB2FcY9ZuhmE7LwiMXFYatawmFXpjZ0QdLkKEvqGcrG0gxi6G9e_Rsa1maUBWLvb3GKU3jXfL5J0YQI_Y6WwJj5c1c8gzBnABulzSR9wak3r9J-wTSM1-doKNIWr1OBeeoj40AR-NwIcj_9BgOGupUTQA-jdV0mQL6q69bVDuwrMJ_ftuC2ojAINWuGcVlF8MaT8phT347rFS8jAfZXKMM2N6gwEbO6Pepgtndg74JcKcwN6jhN0_dWE9XnNH78iwZoQP2nIu1_hojLOiN26-Y3l1xjKUu9WpCrdbIn3jdBIjUs_82pwM2uRqdvLAuiJJVktaJ9CNaky29bihLV1KwcyzQU5zMZ0YdOgvDi7vDHF15FyR2mlywXhx2Pzqs_Gi09Q3CUQ_u0JKiM3_Iyo9RxuzDUZIvZRUtGbu4W2rIWHgKuwGEw6C611ZGtUjORNpEjgHc_861OLJJBSqAIqGgE1tvilyV9y6FbqoXtP5bAfYFuWWl5lmcy9r6s3D3coagPdKlHcrxYxkUETRSyuaCcBo75ilztd3YqgyxVIadbgOwHmU0Cx-mtdwwJOfEdousw2dXnAkdVuG1d4fv6dT6XKyd4x7dyh7CPtVH9O2j65NvIqFE90NfQdNupm_kSKfnt3xCnwzTv155BM4B9tiXd6aKp3d2xIkY57nsTqOTBmTZ6_lf9-EWeHxS_0ukbDYiSVQsFwDz8d0GilKeU&state=AA7-RQyd1KsD63DBoQF_-NfYijzGvptfXTEj8D3AwQzW_ByUe8K0UnLZVuQjE6y8txJMcabFTC4fQhxHqqpTv28_e3dDuLBpYaGKqo_urwHkswmf1pAV2da7nPoVb-n1DHe1P-xU-jzU5c8vlyWCXJPpMDZyR7K0AQ7qdDCQRtr9oPpDymPyYknGIrQB6rI9VRSFinsGhZTnno2AvtOJCkTZfe3abYSdzjB-Am3PI9p-oAwh0f6mBzUGDYCMIB-traI_INV9fSa8tS9K363pBKUBQ-YgKI5nKI8Uqbz5UduNDwB99eQSUaEZu48vabVTwGjsLUczbkA46-u-AKAV65iwTPE6e-zRI11LRgfw4uObam8S3xvL3ok9pESzwGpMlBmEO0goyg9xJa2ULatLOy2PGRcMbWcuhyp84ttzedmiD2gdidVxHafEwgSpSEqad6YLWvCtV4XGbHxyuFZXF8rjFiDUK__KaJ2G-cbzyiXaVQ-YOh80NM8QQmAIPvys-2BTteP_G-1xjRZFpgJO6-dnZw2jelcF8KkITIGTNMuLejrcCyADjusaNOMrHMkASXohnq5p0lpkjPIcEZryghziPu3soPJ8A9jj8K9Ka-CWNosv9aBAnpN4eKYlOBEVljc6W824XPYgYMW62cBHlTlqV8RMNpo_5h6LRf2UdmY2T85xk3Iuz1_1Lr8jeu-UYZILPP2sc7HrjP7eFp70qgMCUQEk_JwsyQ&service=*my_project_id*dev

200 https://gala-demo.appspot.com/app#redirect_state=AA7-RQxBXe_JzFx7iXtcObVa7AJ4qPiiLY_XHrtgX861Z1TlUiOLFM3ymhzxqHWCONLFXjOJQkhNyCsH35cylVBrKtyLDaE-4J7wJ-P9PS3-JEPVeaoRnm7uo4ncLPW5EMxR--onGLFNZydFbqNKhdhWTox3FkUuv2lNZB2FcY9ZuhmE7LwiMXFYatawmFXpjZ0QdLkKEvqGcrG0gxi6G9e_Rsa1maUBWLvb3GKU3jXfL5J0YQI_Y6WwJj5c1c8gzBnABulzSR9wak3r9J-wTSM1-doKNIWr1OBeeoj40AR-NwIcj_9BgOGupUTQA-jdV0mQL6q69bVDuwrMJ_ftuC2ojAINWuGcVlF8MaT8phT347rFS8jAfZXKMM2N6gwEbO6Pepgtndg74JcKcwN6jhN0_dWE9XnNH78iwZoQP2nIu1_hojLOiN26-Y3l1xjKUu9WpCrdbIn3jdBIjUs_82pwM2uRqdvLAuiJJVktaJ9CNaky29bihLV1KwcyzQU5zMZ0YdOgvDi7vDHF15FyR2mlywXhx2Pzqs_Gi09Q3CUQ_u0JKiM3_Iyo9RxuzDUZIvZRUtGbu4W2rIWHgKuwGEw6C611ZGtUjORNpEjgHc_861OLJJBSqAIqGgE1tvilyV9y6FbqoXtP5bAfYFuWWl5lmcy9r6s3D3coagPdKlHcrxYxkUETRSyuaCcBo75ilztd3YqgyxVIadbgOwHmU0Cx-mtdwwJOfEdousw2dXnAkdVuG1d4fv6dT6XKyd4x7dyh7CPtVH9O2j65NvIqFE90NfQdNupm_kSKfnt3xCnwzTv155BM4B9tiXd6aKp3d2xIkY57nsTqOTBmTZ6_lf9-EWeHxS_0ukbDYiSVQsFwDz8d0GilKeU&state=AA7-RQyd1KsD63DBoQF_-NfYijzGvptfXTEj8D3AwQzW_ByUe8K0UnLZVuQjE6y8txJMcabFTC4fQhxHqqpTv28_e3dDuLBpYaGKqo_urwHkswmf1pAV2da7nPoVb-n1DHe1P-xU-jzU5c8vlyWCXJPpMDZyR7K0AQ7qdDCQRtr9oPpDymPyYknGIrQB6rI9VRSFinsGhZTnno2AvtOJCkTZfe3abYSdzjB-Am3PI9p-oAwh0f6mBzUGDYCMIB-traI_INV9fSa8tS9K363pBKUBQ-YgKI5nKI8Uqbz5UduNDwB99eQSUaEZu48vabVTwGjsLUczbkA46-u-AKAV65iwTPE6e-zRI11LRgfw4uObam8S3xvL3ok9pESzwGpMlBmEO0goyg9xJa2ULatLOy2PGRcMbWcuhyp84ttzedmiD2gdidVxHafEwgSpSEqad6YLWvCtV4XGbHxyuFZXF8rjFiDUK__KaJ2G-cbzyiXaVQ-YOh80NM8QQmAIPvys-2BTteP_G-1xjRZFpgJO6-dnZw2jelcF8KkITIGTNMuLejrcCyADjusaNOMrHMkASXohnq5p0lpkjPIcEZryghziPu3soPJ8A9jj8K9Ka-CWNosv9aBAnpN4eKYlOBEVljc6W824XPYgYMW62cBHlTlqV8RMNpo_5h6LRf2UdmY2T85xk3Iuz1_1Lr8jeu-UYZILPP2sc7HrjP7eFp70qgMCUQEk_JwsyQ&service=*my_project_id*_dev   74.125.24.153   normal  none    none

我还注意到在身份验证的最后一步有一个错误 400:

{
  "error": {
    "code": 400,
    "message": "Bad response from IdP in Auth Code Exchange",
    "status": "FAILED_PRECONDITION"
  }
}

    Request URL: https://oauthintegrations.googleapis.com/v1/token:getForService
    Request Method: POST
    Status Code: 400
    Remote Address: 74.125.24.95:443
    Referrer Policy: no-referrer-when-downgrade
    access-control-allow-origin: https://gala-demo.appspot.com
    access-control-expose-headers: content-encoding,date,server,content-length
    alt-svc: quic=":443"; ma=2592000; v="43,42,41,39,35"
    cache-control: private
    content-encoding: gzip
    content-length: 136
    content-type: application/json; charset=UTF-8
    date: Thu, 05 Jul 2018 13:17:41 GMT
    server: ESF
    status: 400
    vary: Origin, X-Origin, Referer
    x-content-type-options: nosniff
    x-frame-options: SAMEORIGIN
    x-xss-protection: 1; mode=block
    Provisional headers are shown
    Authorization: Bearer *my access_token*
    Content-Type: application/json
    Origin: https://gala-demo.appspot.com
    Referer: https://gala-demo.appspot.com/app
    User-Agent: *my user agent*
    {credential: {,…}, gdiState: "APP_AUTH", serviceId: "ardent-fusion-209108_dev",…}
    credential
    :
    {,…}
    gdiState
    :
    "APP_AUTH"
    scopes
    :
    ["https://mail.google.com/"]
    serviceId
    :
    "*my_project_id*_dev"

任何帮助将非常感激!如果您需要更多信息,请发表评论。感谢,并有一个愉快的一天!:)

更新:我已经意识到omniauth 遵循auth 代码流。因此,我将链接流程更改为身份验证代码并添加/users/auth/google_oauth2为我的身份验证 URL 和/users/auth/google_oauth2/callback我的令牌 URL。但是,即使我已将my_app.com/users/auth/google_oauth2/callbackandmy_app.com/users/auth/google_oauth2和 and添加oauth-redirect.googleusercontent.com/r/my_proj_id到我的 oauth 客户端的授权 uri 重定向中,现在仍然存在 redirect_uri_mismatch 错误。从那以后,我尝试在客户端的重定向 uri 中添加尾随 /,以及将 https 替换为 http 并在每个 uri 前面添加 www,但所有这些方法都不起作用。(以上所有网址都带有 https;我的声誉太低,无法发布超过 8 个链接,所以我不得不省略它们)

新的错误日志如下:

2018-07-06T10:06:48.542310+00:00 app[web.1]: I, [2018-07-06T10:06:48.542182 #4]  INFO -- : [2270a384-f7a5-4b6a-9dce-a6999dc47b28] Started POST "/users/auth/google_oauth2/callback/" for 66.249.83.158 at 2018-07-06 10:06:48 +0000

2018-07-06T10:06:48.542796+00:00 app[web.1]: I, [2018-07-06T10:06:48.542726 #4]  INFO -- omniauth: (google_oauth2) Callback phase initiated.

2018-07-06T10:06:48.651257+00:00 app[web.1]: E, [2018-07-06T10:06:48.651082 #4] ERROR -- omniauth: (google_oauth2) Authentication failure! invalid_credentials: OAuth2::Error, redirect_uri_mismatch: Bad Request

2018-07-06T10:06:48.651261+00:00 app[web.1]: {
2018-07-06T10:06:48.651264+00:00 app[web.1]:   "error" : "redirect_uri_mismatch",
2018-07-06T10:06:48.651266+00:00 app[web.1]:   "error_description" : "Bad Request"
2018-07-06T10:06:48.651268+00:00 app[web.1]: }

2018-07-06T10:06:48.652619+00:00 app[web.1]: I, [2018-07-06T10:06:48.652524 #4]  INFO -- : [2270a384-f7a5-4b6a-9dce-a6999dc47b28] Processing by Users::OmniauthCallbacksController#failure as JSON

2018-07-06T10:06:48.652781+00:00 app[web.1]: I, [2018-07-06T10:06:48.652696 #4]  INFO -- : [2270a384-f7a5-4b6a-9dce-a6999dc47b28]   Parameters: {"grant_type"=>"authorization_code", "code"=>"*my_auth_code*", "redirect_uri"=>"https://oauth-redirect.googleusercontent.com/r/*my_proj_id*", "client_id"=>"*my_client_id*", "client_secret"=>"*my_client_secret*"}

4

1 回答 1

1

让我们看看出了什么问题,而不是试图解决它,一个完全不同的解决问题的方法应该会更好。

出了什么问题(以及一些背景)

使用 Actions on Google 的传统身份验证要求您设置 OAuth 服务器。当用户在他们的操作中需要经过身份验证的用户时,它会将他们定向到您的 OAuth Web 服务器进行登录,期望您的服务器将访问令牌或身份验证代码发回给它,可能会做一些进一步的工作来获得一个身份验证令牌,然后在每次调用您的 webhook 实现时向您发送访问或身份验证令牌。然后,您可以使用此令牌来确定用户是谁并采取适当的行动。

看起来正在发生的事情是,助手正在将用户发送到您的登录点,其中显示“完成后,使用访问令牌重定向回此处”的信息。那部分似乎很好。您正在经历包括 Google 登录在内的登录过程。在其中的某个时刻,您将重定向回 Google 助理想要的同一个 URL。

问题是,它不是发送回访问令牌,而是发送一次性身份验证代码。助手得到了这个,因为它不是它被配置为处理的,所以会出现错误。

目前尚不清楚为什么它发送代码而不是访问令牌。可能是 OmniAuth 设计为使用“身份验证代码”方法,而您已将助手配置为使用“隐式”方法。或者可能是登录和助手都使用相同的 URL 作为过程的一部分,这会造成混乱。或者可能是 OmniAuth 并不是真的要扮演 OAuth 服务器的角色。

如果您真的想走这条路,请调查 OmniAuth 配置并考虑更改其或操作的配置。

更新:听起来它使用了不正确的身份验证流程,我很高兴你已经解决了这个问题。您应该为 OmniAuth 设置的授权 redirect_uri 必须正是Google 作为其请求的一部分发送的内容:https://oauth-redirect.googleusercontent.com/r/my_project_id

但是......你可能不需要这个。

使用 Google 登录进行帐户关联

由于您使用 Google 登录在您的 web 应用程序中登录用户,因此您可以避免整个 OAuth 服务器问题并利用现在可用的快捷方式。如果您的 web 应用程序和您的操作都是同一个 Google Cloud 项目的一部分,那么一旦用户对项目进行了身份验证, Google Sign In for the Assistant就会向您发送用户的 ID 令牌。他们可以通过 Action 中的语音或使用 Google Sign In 登录 web 应用程序来验证自己的身份。

发送的 ID 令牌不是身份验证令牌。但是,如果您保存了登录到您的 web 应用程序的用户的身份验证令牌和刷新令牌,您可以使用 ID 令牌中的信息来查找并使用这些信息。

作为其中的一部分,最大的“陷阱”是您只需要通过您的 web 应用程序请求额外的范围 - 作为操作的一部分,没有办法做到这一点。然而,这不是一个主要障碍 - 它只是意味着如果用户在没有 ID 的情况下访问您的操作,请引导他们首先登录到您的 web 应用程序。

请参阅此 Stack Overflow 问题的进一步讨论和图表

于 2018-07-05T17:48:46.687 回答