简体   繁体   English

Google 隐式帐户链接上的操作在模拟器/浏览器中有效,但在设备上无效(通过 Google Home 应用)

[英]Actions on Google implicit account linking works in simulator/browser, but not on device (via Google Home app)

I've implemented the implicit flow for Actions on Google account linking, and am using Dialogflow (previously API.AI) to define intents.我已经为 Actions on Google 帐户链接实现了隐式流程,并且正在使用 Dialogflow(以前是 API.AI)来定义意图。

The full flow works in the device simulator (from AOG).完整流程在设备模拟器(来自 AOG)中工作。 The first intent gets a "It looks like your account isn't linked yet..." response, and the debug pane includes a URL to initiate linking:第一个意图得到“看起来您的帐户尚未链接...”响应,并且调试窗格包含一个用于启动链接的 URL:

https://assistant.google.com/services/auth/handoffs/auth/start?account_name=[account]@gmail.com&provider=[project_id]_dev&scopes=email&return_url=https://www.google.com/ https://assistant.google.com/services/auth/handoffs/auth/start?account_name=[account]@gmail.com&provider=[project_id]_dev&scopes=email&return_url=https://www.google.com/

If I follow this URI in a cache-less window:如果我在无缓存窗口中遵循此 URI:

  1. I'm redirected to my app's authentication page我被重定向到我的应用程序的身份验证页面
  2. I choose to sign in with my Google account (same as [account] above)我选择使用我的 Google 帐户登录(与上面的 [帐户] 相同)
  3. I'm redirected to google.com with a success message in the URI bar我被重定向到 google.com,并在 URI 栏中显示成功消息
  4. The simulator now accepts actions via my app and responds correctly模拟器现在通过我的应用程序接受操作并正确响应

However, if I follow the same flow using a physical Google Home & the gH app for Android.但是,如果我使用物理 Google Home 和适用于 Android 的 gH 应用程序遵循相同的流程。

  1. Device tells me account not yet linked设备告诉我帐户尚未关联
  2. Open Google home and follow 'Link to [my app]' link打开 Google 主页并点击“链接到 [我的应用]”链接
  3. Browser opens to authentication page浏览器打开认证页面
  4. Sign in as user以用户身份登录
  5. Redirected to a white page with a single link "Return to app", which has an href: about:invalid@zClosurez重定向到带有单个链接“返回应用程序”的白页,其中包含一个 href: about:invalid@zClosurez

Linking was unsuccessful, so additional attempts to run intents on the Google Home get the same "Account not yet linked" response.链接失败,因此在 Google Home 上运行 Intent 的其他尝试会得到相同的“帐户尚未链接”响应。

I've inspected the intermediate access_token and state variables at length, and they all match and look to be correctly formatted:我已经详细检查了中间 access_token 和状态变量,它们都匹配并且看起来格式正确:

Authentication URL (app sign in page): https://flowdash.co/auth/google?response_type=token&client_id=[client_id]&redirect_uri=https://oauth-redirect.googleusercontent.com/r/[project_id]&scope=email&state=[state]身份验证 URL(应用登录页面): https : //flowdash.co/auth/google?response_type=token&client_id=[client_id]&redirect_uri=https : //oauth-redirect.googleusercontent.com/r/[project_id]&scope=email&state =[状态]

After authenticating, redirected to (this is the white screen with 'return to app' broken link): https://oauth-redirect.googleusercontent.com/r/genzai-app#access_token=[token]&token_type=bearer&state=[state]身份验证后,重定向到(这是带有“返回应用程序”断开链接的白屏): https : //oauth-redirect.googleusercontent.com/r/genzai-app#access_token=[token]&token_type=bearer&state=[state ]

So, it seems there's something non-parallel about the way the simulator and physical devices work in terms of implicit flow account linking.因此,就隐式流量帐户链接而言,模拟器和物理设备的工作方式似乎有些不平行。

I've been struggling with this, and with the AOG support team for a very long time to no avail.我一直在为此苦苦挣扎,并且与 AOG 支持团队合作了很长时间都无济于事。 Anyone else see a similar issue?还有其他人看到类似的问题吗?

Updated with response redirect code:更新了响应重定向代码:

Login handled by react-google-login component with profile & email scopes.由具有配置文件和电子邮件范围的 react-google-login 组件处理的登录。 On success we call:成功后,我们称之为:

finish_auth(id_token) {
    let provider = {
            uri: '/api/auth/google_auth',
            params: ['client_id', 'redirect_uri', 'state', 'response_type'],
            name: "Google Assistant"
        }
    if (provider) {
        let data = {};
        provider.params.forEach((p) => {
            data[p] = this.props.location.query[p];
        });
        if (id_token) data.id_token = id_token;
        api.post(provider.uri, data, (res) => {
            if (res.redirect) window.location = res.redirect;
            else if (res.error) toastr.error(res.error);
        });
    } else {
        toastr.error("Provider not found");
    }
}

provider.uri hits this API endpoint: provider.uri 命中此 API 端点:

def google_auth(self):
    client_id = self.request.get('client_id')
    redirect_uri = self.request.get('redirect_uri')
    state = self.request.get('state')
    id_token = self.request.get('id_token')
    redir_url = user = None
    if client_id == DF_CLIENT_ID:
        # Part of Google Home / API.AI auth flow
        if redirect_uri == "https://oauth-redirect.googleusercontent.com/r/%s" % secrets.GOOGLE_PROJECT_ID:
            if not user:
                ok, _email, name = self.validate_google_id_token(id_token)
                if ok:
                    user = User.GetByEmail(_email, create_if_missing=True, name=name)
            if user:
                access_token = user.aes_access_token(client_id=DF_CLIENT_ID)
                redir_url = 'https://oauth-redirect.googleusercontent.com/r/%s#' % secrets.GOOGLE_PROJECT_ID
                redir_url += urllib.urlencode({
                    'access_token': access_token,
                    'token_type': 'bearer',
                    'state': state
                })
                self.success = True
        else:
            self.message = "Malformed"
    else:
        self.message = "Malformed"
    self.set_response({'redirect': redir_url}, debug=True)

I am able to make it work after a long time.我能够让它在很长一段时间后工作。 We have to enable the webhook first and we can see how to enable the webhook in the dialog flow fulfillment docs If we are going to use Google Assistant, then we have to enable the Google Assistant Integration in the integrations first.我们必须先启用 webhook,我们可以在对话流实现文档中看到如何启用 webhook 如果我们要使用 Google Assistant,那么我们必须首先在集成中启用 Google Assistant 集成。 Then follow the steps mentioned below for the Account Linking in actions on google:-然后按照下面提到的步骤在谷歌上的操作中进行帐户链接:-

Go to google cloud console -> APIsand Services -> Credentials -> OAuth 2.0 client IDs -> Web client -> Note the client ID, client secret from there -> Download JSON - from json note down the project id, auth_uri, token_uri -> Authorised Redirect URIs -> White list our app's URL -> in this URL fixed part is https://oauth-redirect.googleusercontent.com/r/ and append the project id in the URL -> Save the changes转到谷歌云控制台 -> APIsand Services -> Credentials -> OAuth 2.0 客户端 ID -> Web 客户端 -> 记下客户端 ID,客户端密码 -> 下载 JSON - 从 json 记下项目 ID,auth_uri,token_uri - > 授权重定向 URI -> 将我们应用程序的 URL 列入白名单 -> 在此 URL 固定部分是https://oauth-redirect.googleusercontent.com/r/并在 URL 中附加项目 ID -> 保存更改

Actions on Google -> Account linking setup 1. Grant type = Authorisation code 2. Client info 1. Fill up client id,client secrtet, auth_uri, token_uri 2. Enter the auth uri as https://www.googleapis.com/auth and token_uri as https://www.googleapis.com/token 3. Save and run 4. It will show an error while running on the google assistant, but dont worry 5. Come back to the account linking section in the assistant settings and enter auth_uri as https://accounts.google.com/o/oauth2/auth and token_uri as https://accounts.google.com/o/oauth2/token 6. Put the scopes as https://www.googleapis.com/auth/userinfo.profile and https://www.googleapis.com/auth/userinfo.email and weare good to go. Actions on Google -> Account linking setup 1. Grant type = Authorization code 2. Client info 1. 填写客户端 id,client secrtet, auth_uri, token_uri 2. 输入 auth uri 作为https://www.googleapis.com/auth和 token_uri 为https://www.googleapis.com/token 3. 保存并运行 4. 在谷歌助手上运行时会显示错误,但不要担心 5. 回到助手设置中的帐户链接部分,然后输入 auth_uri 作为https://accounts.google.com/o/oauth2/auth和 token_uri 作为https://accounts.google.com/o/oauth2/token 6. 将范围设为https://www.googleapis。 com/auth/userinfo.profilehttps://www.googleapis.com/auth/userinfo.email和weare 好去。 7. Save the changes. 7. 保存更改。

In the hosting server(heroku)logs, we can see the access token value and through access token, we can get the details regarding the email address.在托管服务器(heroku)日志中,我们可以看到访问令牌值,通过访问令牌,我们可以获得有关电子邮件地址的详细信息。

Append the access token to this link " https://www.googleapis.com/oauth2/v1/userinfo?access_token= " and we can get the required details in the resulting json page.将访问令牌附加到此链接“ https://www.googleapis.com/oauth2/v1/userinfo?access_token= ”,我们可以在生成的 json 页面中获取所需的详细信息。

`accessToken = req.get("originalRequest").get("data").get("user").get("accessToken")
r = requests.get(link)
print("Email Id= " + r.json()["email"])
print("Name= " + r.json()["name"])`

Not sure which python middleware or modules you are using but不确定您使用的是哪个 python 中间件或模块,但是

self.set_response({'redirect': redir_url}, debug=True)

seems to be setting parameters for a returning a response which isn't correct.似乎正在为返回不正确的响应设置参数。 Instead you should redirect your response to the redirect_url.相反,您应该将您的响应重定向到 redirect_url。 For example importing the redirect module in Flask or Django like: from flask import redirect or from django.shortcuts import redirect then redirect like:例如在 Flask 或 Django from flask import redirect重定向模块,例如: from flask import redirectfrom django.shortcuts import redirect然后重定向如下:

return redirect(redirect_url)

It appears Google has made a change that has partially solved this problem in that it is now possible to complete the implicit account linking flow outside of the simulator, in the way outlined in my question.谷歌似乎做出了改变,部分解决了这个问题,因为现在可以按照我的问题中概述的方式在模拟器之外完成隐式帐户链接流程。

It seems the problem stemmed from an odd handling (on the AOG side) of the client-side redirect case used after sign in with the Google sign-in button.似乎问题源于对使用 Google 登录按钮登录后使用的客户端重定向案例的奇怪处理(在 AOG 端)。

From Jeff Craig in this thread :从杰夫克雷格在这个线程中

The current workaround, where we provide the "Return to app" link currently what we're able to provide.当前的解决方法,我们提供当前我们能够提供的“返回应用程序”链接。 The issue is with the way that redirecting to custom-scheme URIs is handled in Chrome, specifically, with regard to the redirect happening in the context of a user action.问题在于在 Chrome 中处理重定向到自定义方案 URI 的方式,特别是关于在用户操作上下文中发生的重定向。

XHR will break that context, so what is happening is that you click the Google Sign-In Button, which triggers an XHR to Google's servers, and then you (most likely) do a client-side redirect back to the redirect_url we supply, our handler executes, and isn't able to do a JS redirect to the custom scheme URI of the app, because were outside of the context of a direct user click. XHR 会打破这个上下文,所以发生的事情是你点击 Google 登录按钮,这会触发一个 XHR 到 Google 的服务器,然后你(最有可能)做一个客户端重定向回到我们提供的 redirect_url,我们的处理程序执行,并且无法执行到应用程序的自定义方案 URI 的 JS 重定向,因为在直接用户单击的上下文之外。

This is more of a problem with the Implicit (response_type=token) flow than with the authorization code (response_type=code) flow, and the "Return to app" link is the best fallback case we currently have, though we are always looking for better solutions here as well.与授权代码 (response_type=code) 流程相比,这对 Implicit (response_type=token) 流程来说更像是一个问题,并且“返回应用程序”链接是我们目前拥有的最佳后备案例,尽管我们一直在寻找这里也有更好的解决方案。

The current behavior shows the 'Return to app' link, but as of last week, this link's href is no longer about:invalid@zClosurez , but instead successfully completes the sign-in and linking process.当前行为显示“返回应用程序”链接,但从上周开始,此链接的 href 不再是about:invalid@zClosurez ,而是成功完成了登录和链接过程。 It's an odd and confusing UX that I hope Google will improve in the future, but it was sufficient to get my app approved by the AOG team without any changes to my flow.这是一个奇怪且令人困惑的 UX,我希望 Google 将来会改进,但它足以让我的应用程序获得 AOG 团队的批准,而无需更改我的流程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM