Sta*_*ley 6 android google-maps ios google-places-api flutter
我有一个用 Flutter 编写的移动应用程序。我正在为地点和地理编码调用 Google API。由于对这些服务的调用是通过在 url 中包含密钥来进行的,因此限制这些密钥非常重要,这样任何人都不能只是拦截并使用它们来拨打许多电话并为我们在 Google 上积累一个大帐户。
API 调用示例如下:
https://maps.googleapis.com/maps/api/place/autocomplete/json?input=$input&types=address&language=$lang&components=country:za&key=$apiKey 和 https://maps.googleapis.com/maps/api /geocode/json?latlng=$lat,$lon&key=$apiKey
(其中 $apiKey=我们的 Google Maps API Credentials Key $input、$lang、$lat 和 $lon 代表其他变量)
Google 目前允许对 API 凭据进行以下应用程序限制:
如果我的密钥没有任何限制(选项“无”),那么我的移动应用程序就可以正常工作。但是,如果我选择将其限制为 iOS 应用程序(并为我的应用程序指定捆绑标识符),我会收到错误消息“此 IP、站点或移动应用程序无权使用此 API 密钥”。当我将密钥限制为 Android 应用程序并为 Android 应用程序指定我的包 ID 和 SHA1 签名时,也会发生同样的情况。
我错过了什么?根据https://developers.google.com/maps/api-key-best-practices#restrict_apikey我应该可以将密钥限制为我的特定移动应用程序。似乎谷歌地图没有发现我确实是从正确的移动应用程序拨打电话。无论我是在模拟器中还是在调试或发布模式下的实际设备上运行它,都会发生错误。(我也从 Test Flight 测试了应用程序的 iOS 版本。当我取消限制时,我的 api 调用工作;当我将它限制为我的 iOS 应用程序的捆绑标识符时,它停止工作。)还有什么我需要配置的? 问题可能是应用程序是用 Flutter 编写的?
我发现一些链接(像这样)表明移动应用程序不应该直接在 url 中使用密钥,而应该使用我们自己的服务器作为 Google 的代理,然后我们应该限制对我们服务器 IP 的访问。这似乎是不必要的开销,因为将密钥限制为特定应用程序 ID 和平台的选项的存在表明这应该是可能的(就像我参考的 Google 文档一样)。
我最终创建了一个代理服务器。(更多内容见下文)。
批判性地思考一下,我意识到 API 实际上没有任何方法可以辨别传入请求是否是从特定移动应用程序发出的,因此我认为对于 https 来说,对特定 iOS 或 Android 应用程序的限制是不可能的要求。
我还研究了一些提供的 flutter 插件,但大多数插件似乎在后台使用google_maps_webservice 。google_maps_webservice 需要应用程序代码中的密钥或指定代理。大多数从 google_maps_webservice 派生的插件甚至不提供代理选项,并且需要指定密钥。因此,即使使用这些插件,最终也会“泄露”应用程序代码中的密钥,这使得逆向工程并获取您的代码成为可能。(它最终位于 iOS 上的 AppDelegate.m 文件和 Android 上的 AndroidManifest.xml 文件中)。Google 建议不要以这种方式泄露您的 api 密钥。
所以我最终创建了一个代理服务器。在没有密钥的情况下向我的代理发出请求,然后代理在添加密钥后将请求传递给 Google。然后代理将响应返回给应用程序。应用程序以及应用程序和服务器之间的流量从不包含密钥。
幸运的是,我的应用程序已经在使用 AWS,并且用户正在使用 Cognito 登录。因此,我可以在 API Gateway 中轻松创建代理,并让应用程序使用 Cognito 对我的代理服务器进行身份验证。这确保只有在 Cognito 中有效登录我的应用程序的用户才能调用代理,并且密钥始终保密。
归档时间: |
|
查看次数: |
550 次 |
最近记录: |