问题描述
我一直在使用自己的使用Google Places API的简单客户端服务来快速使用Google Places Search。 我注意到还有其他专门为Android和IOS设计的SDK-(适用于Android / IOS的Places SDK)
当我查看API的密钥限制时,我意识到Google Places API似乎设计用于服务器端应用程序(密钥可以限制于某些IP),而不能局限于Android / IOS应用。
据我所知,每个人都可以破解应用程序,然后可以获得API。 这是在Flutter中使用Google地方搜索的更安全方法吗?
解决方法
我假设您是指GG服务的API密钥。像大多数API服务提供商一样,使用具有最低安全性措施的服务是关键。拥有防止滥用的保护措施的确是服务(您)的承租人。
假设您经营一家面包店,而Google则通过带钥匙的门为您提供面包。如果您的所有客户都可以访问该密钥,则他们将打开并使用所需的任意数量的面包。解决方案是让您将后门放在后门,只有您的员工(您的程序/服务)可以访问。然后客户可以购买您的面包,并且可以将面包装饰得更漂亮以提高价格。
我不认为这仅与Flutter有关。问题是您需要保护该API密钥。完全不允许用户访问它。一些防御技术可以实现。我建议您阅读以下简短列表:https://dev.to/bearer/api-security-best-practices-3gjl
,pubspec.ymal
flutter_inappwebview: ^5.3.2
main.dart
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
class MyChromeSafariBrowser extends ChromeSafariBrowser {
@override
void onOpened() {
print("ChromeSafari browser opened");
}
@override
void onCompletedInitialLoad() {
print("ChromeSafari browser initial load completed");
}
@override
void onClosed() {
print("ChromeSafari browser closed");
}
}
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
if (Platform.isAndroid) {
await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
}
runApp(MaterialApp(home: MyApp(),theme: new ThemeData(scaffoldBackgroundColor: const Color(0xFFA7A5A5)),debugShowCheckedModeBanner: false));
}
class MyApp extends StatefulWidget {
final ChromeSafariBrowser browser = new MyChromeSafariBrowser();
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
// @override
// void initState() {
// widget.browser.addMenuItem(new ChromeSafariBrowserMenuItem(
// id: 1,// label: 'Custom item menu 1',// action: (url,title) {
// print('Custom item menu 1 clicked!');
// }));
// super.initState();
// }
TextEditingController controller=TextEditingController();
var urlString="";
launchUrl()
async {
String prefix = "https://www.google.com/search?q=";
urlString=controller.text;
if(!urlString.startsWith("http://") && !urlString.startsWith("https://")&&
!urlString.endsWith(".com") && !urlString.endsWith(".as") &&
!urlString.endsWith(".uk") && !urlString.endsWith(".biz")&&!urlString.endsWith(".in")|| urlString.contains(" ") )
{
urlString=prefix+urlString;
}
if(urlString.endsWith(".com") || urlString.endsWith(".as") || urlString.endsWith(".uk") || urlString.endsWith(".biz")||urlString.endsWith(".in") )
{
if(!urlString.startsWith("http://") && !urlString.startsWith("https://"))
{
urlString = "http://"+urlString;
}
}
await widget.browser.open(
url: Uri.parse(urlString),options: ChromeSafariBrowserClassOptions(
android: AndroidChromeCustomTabsOptions(
addDefaultShareMenuItem: false,),ios: IOSSafariOptions(barCollapsingEnabled: true)));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: TextField(
autofocus: false,controller: controller,cursorColor: Colors.black,textInputAction: TextInputAction.search,onSubmitted: (url)=>launchUrl(),style: TextStyle(color: Colors.black),decoration: InputDecoration(
border:InputBorder.none,hintText: "Search Google Or Enter URL",hintStyle: TextStyle(color:Colors.grey),filled: true,fillColor: Colors.white,prefixIcon: Icon(Icons.search),body:
SingleChildScrollView(
scrollDirection: Axis.vertical,child:
Column(children: <Widget>[
Row(children: <Widget>[
Container(
// padding: EdgeInsets.all(50),alignment: Alignment.center,margin: const EdgeInsets.only(top: 30.0,left:10.0),child:
Text(
'youtube.com/bappasaikh',style: TextStyle(fontSize: 25),]),);
}
}