如何将Google Maps地点,地理编码API调用适当地限制为Android和iOS应用程序使用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=$apiKeyhttps://maps.googleapis.com/maps/api/geocode/json?latlng=$lat,$lon&key=$apiKey

(其中$ apiKey =我们的Google Maps API凭据密钥$ input,$ lang,$ lat和$ lon代表其他变量)

Google当前允许对API凭据进行以下应用程序限制:

  • 没有
  • HTTP Referrers
  • IP地址
  • Android应用
  • iOS应用

当我对密钥没有任何限制(选项“无”)时,我的移动应用程序可以正常工作。但是,如果我选择将其限制为iOS应用程序(并为我的应用程序指定捆绑包标识符),则会出现错误该IP,站点或移动应用程序无权使用此API密钥”。当我将密钥限制为Android Apps并为Android应用程序指定我的Package ID和SHA1签名时,也会发生同样的情况。

我想念什么?根据{{​​3}},我可以将密钥限制为特定的移动应用程序。我确实从正确的移动应用程序拨打电话,看来Google Maps没有接听电话。无论我是在模拟器中还是在调试或发布模式下的实际设备上运行此错误,都会发生该错误。 (我也已经从Test Flight中测试了该应用程序的iOS版本。删除限制后,我的api调用起作用;当我仅将其限制为我的iOS应用程序的Bundle Identifier时,它就停止了工作。)我还需要配置其他内容吗? ?问题可能出在应用程序是用Flutter编写的吗?

我找到了一些链接(例如https://developers.google.com/maps/api-key-best-practices#restrict_apikey),这些链接建议移动应用程序永远不要直接在网址中使用密钥,而应该使用自己的服务器作为Google的代理,然后我们应限制对服务器的访问IP。这似乎是不必要的开销,因为将密钥限制为特定应用程序ID和平台的选项的存在表明,这应该是可能的(我引用的Google文档也是如此)。

解决方法

我最终创建了代理服务器。 (有关以下内容的更多信息。)

对此进行了认真的思考,我意识到API确实没有任何办法可以识别传入请求是否来自特定的移动应用程序,因此我认为对特定的iOS或Android应用程序的限制并不是真的可以用于https请求。

我还调查了所提供的一些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中有效登录我的应用程序的用户才能调用代理,并且密钥始终保持机密。

,

如果您想为特定的Android / iOS应用利用Google Map Service API配置,则需要使用本机Android和本机iOS SDK,具体取决于SHA指纹和程序包名称或捆绑包ID。

由于Google Places API似乎很流行,因此存在许多第三方尝试:https://pub.dev/packages?q=google+places

存在类似的地理编码情况:https://pub.dev/packages?q=google+geocoding

您可以查看是否有适合您的应用程序,或者您需要创建自己的平台渠道来获得支持:https://flutter.dev/docs/development/platform-integration/platform-channels