2010-02-13 65 views
69

目前Google要求您创建一个API密钥,该密钥是特定于要从其提供地图的域的API密钥。 Google如何执行此操作?我想做同样的事情。Google地图如何保护其API密钥?如何做出类似的东西?

我为我的服务公开了一个API,但希望允许客户端通过javascript嵌入对API的调用,而不仅仅是从服务器。我可以使用随机令牌来保护它,但当然这可能很容易被任何人在客户端机器上查看代码所欺骗。

我总是理解这个概念是不可能的,但谷歌在执行它方面做得很好。

编辑 - 这听起来像谷歌真的没有做任何惊人的毕竟。他们的API很可能只是用于跟踪,而不是真的保证他们的API被密钥使用者所使用。

+0

我相信我找到了答案。 – 2010-02-13 03:26:49

回答

27

我很确定他们使用REFERER URL来确定来电的来源。如果域与分配给密钥的内容不匹配,则这是无效请求。

举一个实际的例子,使用PHP,您可以使用$_SERVER['HTTP_REFERER']来检查域以检查引用者。如果域匹配,则返回有效的响应。如果没有,您可以返回401 Unauthorized或其他回复。

+0

因此,如果客户端通过JavaScript对我们的API进行AJAX调用,那么我可以依赖Referer Domain来实现准确和非欺骗? – Vyrotek 2010-02-13 03:08:05

+1

没有。这是可欺骗的。我认为谷歌更可能依赖于IP地址(不容易被欺骗)和DNS查询。 – 2010-02-13 03:10:53

+0

啊,所以他们采取域名网址,并查找它的IP和查找DNS,以确保其匹配。虽然,你说这在技术上也是可以欺骗的? – Vyrotek 2010-02-13 03:13:10

-6

它工作的原因是,您无法使用javascript进行API调用。浏览器安全性可以防止JavaScript向除javascript源自的域之外的任何地方发出请求。正因为如此,来自JavaScript的任何API调用都需要通过存储API密钥的服务器进行反弹(api密钥从未被javascript看到)。

+2

虽然有方法(JSONP)。我不认为你不能打电话,你通常无法处理退货。 – 2010-02-13 05:07:32

+0

看几个例子,尤其是http://econym.org.uk/gmap/example_map12.htm(列为一个很好的教程),看起来典型用户在脚本src maps api时显示键。源js覆盖页面(地图是一组img)。通过使用GDownloadUrl()下载json数据来放置标记 - 这只会产生一个XMLHttpRequest,并返回到他的服务器。 JSONP需要谷歌服务器的支持,对吧? – mar 2010-02-16 19:54:41

+4

如果这是真的,那么例如CDN托管的jQuery无法对除CDN以外的任何其他域进行Ajax调用。 – Arjan 2012-09-08 12:35:03

3

正如我的评论说:

引用者是具有欺骗性,所以它可能是不太可能,谷歌将使用它作为验证手段。请参阅this wikipedia entry.

我的猜测是Google可能使用调用者的IP地址以及DNS查找。 DNS并非真正可欺骗,因为您的DNS条目必须正确才能让网站找到您。

但是,即使这样也有问题,因为如果服务器使用循环IP地址DNS设置,Google在执行DNS查找时将被重定向到不同的IP地址。

从FAQ

注意,当网站使用该地址访问的http://www.mygooglemapssite.com/一键才会被接受。如果通过IP地址(例如http://10.1.2.3/)访问网站或通过使用DNS CNAME记录向www.mygooglemapssite.com别名的主机名访问该网站,则不会被接受。

我的猜测是,它可能会使用Host头请求的页面,这将作为工作通常谷歌要求时发送您包括它的API脚本直接进入页面。然后,该脚本可以访问当前页面的标题,并可以使用它来检查。

我的猜测是由于它不适用于IP地址或别名,这意味着它没有执行DNS检查。

这种方法不能被欺骗,因为它必须是正确的标题来访问页面。但是,这意味着域的任何别名都不起作用。

然而,这也意味着你必须提供一个Javascript库访问代码,你可以不检查这个服务器端,我相信。

+0

当请求页面时,'Host'头部可能包含地址,但是我怎样才能保证这个值也会被传递到由该页面对我的API所做的新的AJAX请求中?我认为这基本上是'Referrer'包含的内容,我们知道这可能是欺骗性的。 – Vyrotek 2010-02-13 04:01:04

+0

那么,因为你正在编写AJAX调用(因为你提供了Javascript库),你可以确保它被发送。 – 2010-02-13 04:09:02

+0

Google可能需要API密钥的原因是因为它们提供了Javascript库,然后可以在页面上运行Javascript。 – 2010-02-13 04:10:37

62

的API密钥本身是最有可能的密钥与关联的域和秘密只有谷歌API服务器知道的单向散列。它可能包含其他一些众所周知的(当然是Google的)信息。当您从该域请求时,API服务器将接收请求来自的域,并使用同样的方法进行散列计算并比较这两个值。

对于Ajax调用,他们很可能使用referrer来获取文档主机的域。尽管引用者可能被欺骗,但最终为了使用API​​,您需要在文档中执行Google JavaScript。此时,此JavaScript可以验证调用Ajax API调用的文档是否源自目标服务器。这当然也是可以欺骗的,只要你有自己的DOM实现或者对脚本进行实时修改。但是,这种欺骗行为需要发生在客户端,而且希望使用Google API的网站能够欺骗客户端软件的可能性非常小。

注意,由于API基本上是免费的,他们可能已经提供给他们的API匿名访问也是如此。显然,Google的目的不是保护未经授权的访问,而是确保他们可以收集尽可能多的有关该数据使用情况的数据,并能够将该使用情况与他们收集的有关目标域的其他数据相关联。因此,我不希望API密钥验证比我上面描述的复杂得多 - 更高级方法的ROI太低。

当然,也有通过他们的API可能的XSS攻击的关注。但我不相信他们的API密钥与他们拥有的任何反XSS代码相关的太多。

+0

不幸的是这听起来像是最合理的答案。感谢您的输入。 – Vyrotek 2010-02-13 06:01:42

+2

“他们本来可以提供匿名访问” - 请注意,某些功能受限于每天的请求数和API密钥(并且在发布时)。反向地理定位。 – Piskvor 2011-10-21 09:57:20

+1

另请注意,HTTPS上的使用不是免费的。 – Arjan 2012-09-08 12:28:51

2

我同意所有的弗郎佩诺夫具有listed.I想阐述使用别人的API密钥一点点点。让我们假设您使用http://mysite.com注册了key1。

1)第一次尝试 - 如果anothersite.com有脚本src = http://www.google.com/jsapi?key=key1,谷歌可能会检查引用(哈希方案提到),在这种情况下,有一个不匹配。邪恶攻击者如何克服这一点 - 很多人都提到引用者可能被欺骗。这并不适用于此。如果你提出请求,你肯定可以发送任意头文件,但邪恶的黑客如何为anothersite.com上的用户推荐引用者 - 这通常不容易。在IE 6上有过旧版本的Flash,允许攻击者在发出跨域请求时设置任意标题,但通常这对脚本src无效。我不确定包含的js是否对document.location进行了任何验证以防止发生(可能不是)。

2)第二次尝试 - 邪恶攻击副本谷歌的javascript从mysite.com页面源的API密钥,然后在中嵌入修改anothersite.com的JavaScript。现在谷歌无法检查任何东西(远程IP将是用户的计算机,并没有很多你或谷歌可以做的)。因此,如果你想出于某种原因保持你的API密钥的秘密(其中一个原因,恶意的人可以把你的密钥列入黑名单/阻止),那么不要通过你的服务器在客户端和代理请求中嵌入密钥(你的应用程序代码现在有钥匙)。