使用谷歌地图js API时是否需要隐藏API密钥?如果是这样,怎么样?

时间:2016-07-01 20:53:11

标签: javascript html google-maps google-maps-api-3

根据https://developers.google.com/maps/documentation/javascript/tutorial#HTML5, 似乎我可以将以下标记添加到我的html并开始使用maps js API。

<script async defer
      src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>

但这会泄露我的API密钥。

在google上搜索并在stackoverflow上浏览答案后,我觉得可能没有必要隐藏此API密钥。我只需要在google上创建API密钥时设置引用,如中所述 https://stackoverflow.com/a/2256312/1316649

因此,即使其他人知道我的API密钥,他们也无法从其他域使用它。我是对的吗?

但谷歌表示你不应该在代码中嵌入API密钥: https://support.google.com/cloud/answer/6310037

那么,在使用google maps js API时是否需要隐藏API密钥?如果是这样,怎么样?

更新:通过'API密钥',我的意思是浏览器API密钥。

7 个答案:

答案 0 :(得分:12)

Google地图有多种类型的API密钥。有嵌入客户端库时使用的浏览器密钥,可以向人们透露(你需要在客户端使用它,所以你无论如何都无法避免)。然后是服务器端密钥,用于诸如地理编码服务之类的事情。应该保密。

请确保您使用的是浏览器密钥。

答案 1 :(得分:4)

您发布的说明您不应在代码中嵌入API密钥的链接与Google的云平台相关。您可以在代码中保留Google地图的API密钥。

答案 2 :(得分:4)

虽然上述答案很有帮助,但它们都没有解决以下漏洞:

一旦用户有权访问您的API密钥,即使他们仅限于从您的域中使用它,他们仍然可以根据需要使用它。从最粗糙的意义上讲,这可能意味着在很短的时间内刷新一百万页(并映射负载),从而使您超出使用配额。

我还没有找到解决此问题的任何解决方案。除非我错过了什么......?

Relevant usage limits for google maps javascript api here.

答案 3 :(得分:2)

我建议将您的API密钥限制为仅供IP地址使用。需要它们的引荐来源网址:通过限制IP地址,引荐来源网址,您可以减少受损API密钥的影响。

您可以通过打开“凭据”页面指定可以使用控制台中每个键的主机和应用,然后使用所需设置创建新的API密钥,或者编辑API密钥的设置。

这可以帮助您保护API密钥。

杰夫

答案 4 :(得分:0)

摘自Google Maps API文档here

API key restrictions and best practices

------------------------------------------------------------------------
|    API/SDK/Service    |                 Best Practices               |
-----------------------------------------------------------------------|
| Maps JavaScript API   | Restrict your API keys                       |
|                       | Independent API key per app                  |
|                       | Delete API keys no longer needed             |
|                       | Exercise caution when regenerating keys      |
|                       | Monitor API key usage for anomalies          |
-----------------------------------------------------------------------|
| Maps Static API       | Restrict your API keys                       |
|                       | Digital signatures                           |
|                       | Independent API key per app                  |
|                       | Delete API keys no longer needed             |
|                       | Exercise caution when regenerating keys      |
|                       | Monitor API key usage for anomalies          |
|                       | Do not embed signing secret directly in code |
|                       | Do not store signing secret in source tree   |
|                       | Review code before public release            |
------------------------------------------------------------------------

如您所见,虽然某些API(例如Maps Static API)确实明确建议您不要将签名机密或API密钥直接嵌入代码中,并采取预防措施以使其不受源代码控制,但是Maps JavaScript API未提及这些注意事项。

只要您遵循其他JavaScript API最佳做法,文档似乎也不会阻止您将密钥提交给源代码管理并将其直接嵌入代码中。

答案 5 :(得分:0)

从文档中:Loading the Maps JavaScript API 使用脚本标签加载Maps JavaScript API,该脚本标签可以内联添加到HTML文件中,也可以动态添加使用单独的JavaScript文件添加。

要使用单独的JavaScript文件动态内联加载Maps JavaScript API,请参见以下示例。这种方法使您可以从单独的.js文件中处理所有与API一起使用的代码,等效于内联添加script标签。


// Create the script tag, set the appropriate attributes
var script = document.createElement('script');
script.src = 'https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap';
script.defer = true;

// Attach your callback function to the `window` object
window.initMap = function() {
  // JS API is loaded and available
};

// Append the 'script' element to 'head'
document.head.appendChild(script);
 

我认为通过动态加载,我们可以将.js文件放在.gitignore文件中,并从github隐藏起来。

但是它仍将作为浏览器中的所有JS代码可见(请参见inspect)。

因此,只需使用动态加载并从后端获取api密钥即可。

答案 6 :(得分:-1)

您需要隐藏API密钥

使用Google Maps js API时,您需要隐藏API密钥。您仅设置引荐来源是不够的。 我的PC上有本地Web服务器,并且可以更改我的hosts文件,因此我可以将HTML的域名欺骗为您的域。 如果您在HTML中显示API密钥,则有人可能会使用该密钥访问Google地图。这可能意味着刷新一百万页(并加载地图)!

这是Google的不好的例子。

<script defer
  src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>

如何从HTML隐藏API密钥

我使用环境变量和CGI从HTML隐藏我的API密钥,如下所示。

1。设置环境变量

我在环境变量中设置了Google Maps API密钥,并将其传递给我的CGI脚本。 nginx + fcgiwrap在我的服务器上运行,因此我在fcgiwrap.conf中这样设置API密钥。

fcgiwrap.conf

location /cgi-bin/ {
    ........
    fastcgi_param GOOGLE_MAPS_API_KEY  YOUR_API_KEY; <= SET YOUR API KEY HERE
}

2。制作CGI脚本

我这样制作了python CGI。这与Google的SAMPLE中的src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY相同。

getapijs.py

#!/usr/bin/python
# -*- coding: utf-8 -*-
import requests
import os
url = 'https://maps.googleapis.com/maps/api/js'
key = os.environ['GOOGLE_MAPS_API_KEY'] # get Environment Variables
mysrc = url + "?key=" + key
response = requests.get(mysrc) # get src from Google Maps url
print("'Content-Type': 'text/javascript; charset=UTF-8'") # header for HTML
print("")
print(response.text)

3。从javascript调用CGI

从window.onload调用您的CGI。这与Google的SAMPLE中的<script defer ... &callback=initMap>相同。

main.js

function initMap() {
    var uluru = {lat: -25.344, lng: 131.036};
    var map = new google.maps.Map(document.getElementById('map'), {zoom: 4, center: uluru});
    var marker = new google.maps.Marker({position: uluru, map: map});
}
window.onload = function() {
    fetch("/cgi-bin/getapijs.py").then(res=>{
        return res.text();
    }).then(mytext => {
        eval(mytext);
    }).then(() => {
        initMap();
    }).catch(() =>{
        // error handling
    });
}

4。阅读HTML中的main.js

在标题部分设置<script src="main.js"></script>

index.html

<!DOCTYPE html>
<html>
  <head>
    <style>
      /* Set the size of the div element that contains the map */
      #map {
        height: 400px;  /* The height is 400 pixels */
        width: 100%;  /* The width is the width of the web page */
      }
    </style>
    <title>Hello World</title>
    <script src="main.js"></script>
  </head>
  <body>
    <h3>My Google Maps Demo</h3>
    <!--The div element for the map -->
    <div id="map"></div>
  </body>
</html>