我已经实施了针对Google帐户关联操作的隐式流程,并使用Dialogflow(以前的API.AI)来定义意图。
完整流程在设备模拟器(来自AOG)中工作。第一个意图得到一个"看起来你的帐户还没有链接......"响应,调试窗格包含一个用于启动链接的URL:
如果我在无缓存窗口中跟踪此URI:
但是,如果我使用物理Google Home& amp;适用于Android的gH应用。
about:invalid@zClosurez
链接未成功,因此在Google Home上运行意图的其他尝试获得相同的"帐户尚未关联"响应。
我已经检查了中间的access_token和状态变量,它们都匹配并且看起来格式正确:
经过身份验证后,重定向到(这是白色屏幕,其中包含'返回应用程序'已断开的链接):https://oauth-redirect.googleusercontent.com/r/genzai-app#access_token=[token]&token_type=bearer&state=[state]
因此,就隐式流量帐户链接而言,模拟器和物理设备的工作方式似乎存在不平行的现象。
我一直在努力解决这个问题,而且AOG支持团队已经很长时间没有用了。其他人看到类似的问题吗?
更新了回复重定向代码:
由react-google-login组件处理的登录与profile&电子邮件范围。成功之后我们称之为:
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点击此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)
答案 0 :(得分:1)
很长一段时间后我能够让它发挥作用。我们必须首先启用webhook,我们可以看到如何在对话框流程实现文档中启用webhook如果我们要使用Google智能助理,那么我们必须首先在集成中启用Google智能助理集成。然后按照下面提到的步骤进行谷歌操作中的帐户关联: -
转到Google云端控制台 - > API和服务 - >凭证 - > OAuth 2.0客户端ID - >网络客户端 - >请注意客户端ID,客户端密码 - >下载JSON - 从json记下项目id,auth_uri,token_uri - >授权重定向URI - >白名单我们的应用程序的URL - >在此网址中,已修复的部分为https://oauth-redirect.googleusercontent.com/r/,并将项目ID附加到网址中 - >保存更改
Google上的操作 - >帐户链接设置1.授予类型=授权代码2.客户信息1.填写客户端ID,客户端secrtet,auth_uri,token_uri 2.输入auth uri为https://www.googleapis.com/auth,token_uri为https://www.googleapis.com/token 3.保存在谷歌助手上运行时会显示错误,但不要担心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.profile和https://www.googleapis.com/auth/userinfo.email,我们就可以了。 7.保存更改。
在托管服务器(heroku)日志中,我们可以看到访问令牌值,通过访问令牌,我们可以获取有关电子邮件地址的详细信息。
将访问令牌附加到此链接“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"])`
答案 1 :(得分:0)
不确定您使用的是哪个python中间件或模块
self.set_response({'redirect': redir_url}, debug=True)
似乎是为返回不正确的响应设置参数。相反,您应该将响应重定向到redirect_url。例如,在Flask或Django中导入重定向模块,如:
from flask import redirect
或from django.shortcuts import redirect
然后像:
return redirect(redirect_url)
答案 2 :(得分:0)
似乎Google已经做出了部分解决此问题的更改,因为现在可以按照我的问题中概述的方式完成模拟器外部的隐式帐户链接流程。
似乎问题源于在使用Google登录按钮登录后使用的客户端重定向案例的奇怪处理(在AOG方面)。
杰夫克雷格在this thread:
当前的解决方法,我们提供"返回应用"链接 目前我们能够提供的。问题在于方式 重定向到自定义方案URI在Chrome中处理,具体而言, 关于在用户操作的上下文中发生的重定向。
XHR将破坏该上下文,所以发生的是你点击 Google登录按钮,可触发XHR到Google的服务器, 然后你(最有可能)做一个客户端重定向回到 我们提供redirect_url,我们的处理程序执行,并且无法执行 JS重定向到应用程序的自定义方案URI,因为它在外面 直接用户点击的上下文。
这是Implicit(response_type = token)流程的一个问题 比授权代码(response_type = code)流,和 "返回app"链接是我们目前最好的后备案例, 虽然我们也一直在寻找更好的解决方案。
当前行为显示“返回应用程序”'链接,但截至上周,此链接的href不再是about:invalid@zClosurez
,而是成功完成登录和关联过程。这是一个奇怪且令人困惑的用户体验,我希望谷歌将来会有所改进,但只要AOG团队批准我的应用程序而不改变我的流量就足够了。