我有一个单页web应用程序,它使用Google Apps脚本执行API来调用返回所需数据的函数。我的项目基于谷歌提供的快速启动示例代码。
这需要使用OAuth,我正在通过使用谷歌提供的客户端JavaScript库的函数来实现这一点。
第一次要求用户验证以下功能时,immediate: false
:
gapi.auth.authorize({client_id: CLIENT_ID, scope: SCOPES, immediate: false}, handler);
后续的API请求还必须提供身份验证令牌,因此我调用相同的函数,但使用immediate: true
:
gapi.auth.authorize({'client_id': CLIENT_ID, 'scope': SCOPES, 'immediate': true}, handler);
每次调用gapi.auth.authorize
,都会向页面添加一个新的IFRAME
,似乎是为了存储验证操作/令牌等的结果。
所以,是的,一切都有效,但我认为必须有更好的方法来做到这一点。
在初始身份验证之后,是否有其他方法可以进行后续API调用,而不需要使用gapi.auth.authorize
并向页面添加另一个IFRAME
根据谷歌:
票据
在初始用户授权后,对使用immediate:true模式的gap.auth.auth.authorize的调用将在没有用户交互的情况下获得授权令牌
简而言之,除非您使用"脱机"模式,否则您无法避免iframe(或弹出窗口,这是较旧的方式)。交易如下:
请求权限有两种不同的方式,"脱机"或"不脱机"。
在Offline中,oauth2通过给你"刷新令牌"给你一个永久权限(好吧,如果用户从谷歌帐户安全页面撤销权限,或者如果用户更改密码,对于某些范围,这并不是永远的)。
这个特殊的令牌允许您随时创建新的访问令牌,只需对API执行"GET"调用,而无需任何用户干预。在你的情况下,这是你需要的模式,没有办法绕过它,这就是它存在的原因,你必须特别注意安全地存储它,等等
在非脱机模式下,您只获得临时权限("访问令牌"将在1小时后过期),而不会获得"刷新令牌"。但这是怎么回事呢?某个地方一定存储了一些刷新令牌或一些私有的东西
使用GoogleAPI客户端库进行JavaScript身份验证利用了浏览器安全功能。特别是,浏览器确保每个子域的存储和cookie安全,一旦您登录浏览器,谷歌网站将存储或使用cookie来保护发送给谷歌以验证您的参数
那么,如何解读这些价值观呢?打开google.com url是让javascript读取值的唯一方法。谷歌允许特殊的参数,这样它就可以通过访问令牌进行通信。如何打开页面?通过"iframe"或"popup"是浏览器目前唯一支持的方式。
这使得谷歌页面可以像一个安全的代理一样向谷歌索要东西。iframe或打开谷歌页面(作为弹出窗口)的页面不能伪造自己的URL,因此这个"代理"知道哪个页面需要数据。然后,代理可以通过谷歌服务器验证这个调用方的作用域,并返回一个新的访问令牌。黑客不能从服务器上伪造,因为它没有所需的cookie(存储在每个用户的浏览器中的谷歌子域下,这是"在线"模式唯一有效的地方)
在浏览器保护iframe之前,"popup"是一种较老的方式,但当弹出窗口打开并立即关闭时,它至少会引起"闪光"(在上面的链接中搜索"jarring")
因此,后来谷歌提供了"iframe"模式,提供了更流畅的体验。使用iframe是上面链接提到的"立即"模式。
TLDR:必须使用"离线"或破解用户的浏览器。