我有一个 Flutter 应用程序,它利用 Google 地图显示地图并调用 Places API 以根据用户的位置检索附近的商店。在开发过程中,我没有限制 API 密钥,但现在我想转向生产,我限制了 Android 和 iOS 密钥
以下是我如何调用 Places API:
final String apiUrl =
"https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${cords.latitude}%2C${cords.longitude}&radius=$radius&type=$type&key=$apiKey";
final response = await http.get(Uri.parse(apiUrl));
我尝试限制 iOS 和 Android 的 API 密钥(每个应用程序 1 个密钥)。地图显示正确,但对地方 API 的调用返回以下错误:
{
"error_message" : "This IP, site or mobile application is not authorized to use this API key. Request received from IP address x.x.x.x, with empty referer",
"html_attributions" : [],
"results" : [],
"status" : "REQUEST_DENIED"
}
经过一段时间的搜索,我发现了一个 Stack Overflow 帖子,建议一些 google 地图 API 被设计为从后端系统调用,而不是直接从前端调用。以下是该帖子的链接供参考:Android Google Maps Direction Api - Api key limit notworking
这让我想到也许我也会遇到这种情况。根据用户提供的链接,事实证明它实际上是......(如果我弄错了,请告诉我)
我正在考虑修改调用 Places API 的方式。由于我已经使用 Firebase,因此我正在考虑触发 Cloud Function 来进行 Places API 调用,然后将 JSON 响应转发到客户端电话。但是,我不确定是否应该限制云功能的 API 密钥。
我的问题是:
如果您相信我可以用另一种方式解决这个问题,请告诉我,我还注意到表格上有适用于 android 和 iOS 的 Places SDK 的条目,可以限制为应用程序,但我不知道它是否适合我案例是因为我正在使用 flutter。
需要澄清的事情:
任何建议或见解将不胜感激。预先感谢您。
我最终所做的实际上是使用可调用的云函数,因为我已经在使用 firebase 并且实现了 App Check 以确保只有我的应用程序可以触发该函数并确保 api 密钥的安全,我使用了谷歌云秘密管理器.
这也是一个很好的做法,建议将其限制为您要使用的特定 API
对于任何对如何保护敏感信息感兴趣的人,Cloud Functions for Firebase 与 Google Cloud Secret Manager 集成。
https://firebase.google.com/docs/functions/config-env?gen=2nd#create-secret
export const fetchFromGoogleMaps = functions.onCall({
secrets: ["secret_name"],
enforceAppCheck: true,
}, async (request) => {
const apiKey = process.env.secret_name;
const apiUrl = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${latitude}%2C${longitude}&radius=${radius}&type=${type}&key=${apiKey}`;
return await axios.default.get(apiUrl).then((apiResponse) => {
// ...
}).catch((error) => {
// handle the error
});