Google API Client side usage - is the API Key mandatory? - ios

I am using Google directions and geocode services in my iOS App, and it works fine. I am also using Google maps API.
For google maps, I am using an API Key, but for geocoding and directions services, I am calling them as any REST Webservice, without adding the API Key parameter, and it works.
My questions here are
Is the API Key mandatory for client-side calls ? Is it legal ?
If not, what are the risks?
If I add an API Key, the 2500 query per day per key limit will apply, or the limit will be per users IP address?
In https://developers.google.com/maps/documentation/directions/ I can read
All Directions API applications should use an API key
In https://developers.google.com/maps/documentation/geocoding/ I can read
All Geocoding API applications should use an API key
At the same time, I am not using Server side Geocoding/Directions, but Client side calls, and for now, I haven't sent any ApiKey when using it.

A key is not required for these webservices, they may work without.
The difference is the quota: without a key it will be based on the IP-address of the server. When your domain shares the same IP-address with other domains(usually it's the case) you will also share your quota with these domains.
The result: when applications placed at other domains with the same IP(may be houndreds) also request these services(without a key) you'll often hit the limits.
When you use the services on clientside(via the methods of the maps-Javascript-API) it doesn't matter at all, any limit will apply to the user of your application, not to the application.

Related

The provided API key is expired (for Directions API)

I have looked into the first 15 "similar questions" to my question and none resolved my issue. Sometimes, the error I am getting for the same API request is "This IP, site or mobile application is not authorized to use this API key. Request received from IP address {*ip_address*}, with empty referer". I also searched for that and none of the solutions suggested helped in my case.
My current situation
I am calling https://maps.googleapis.com/maps/api/directions/json?key=MYKEY&some_other_params in an iOS project
I am using an API key that is restricted to a Bundle ID
I have a list of items (let's refer to it as location items) that when clicked I call the Direction API to get route info
I am getting the two errors I mentioned above interchangeably. That means sometimes I get the expired error and sometimes I get the IP error. I get the errors for the same location item.
APIs enabled:
Directions API
Geolocation API
Maps SDK for iOS
Geocoding API
Places API
The Bundle ID is not the problem
I know that my Bundle ID is correct as I am using it with another service, which is Firebase. To eliminate the silly mistake of mistyping, I copied the same Bundle ID from my Firebase API credential. My API key for Firebase is restricted to the same Bundle ID and to the Firebase service. It is working without any issues.
API restrictions only
To eliminate the Bundle ID issue, I also tried None for the Application restrictions and chose to restrict APIs. I added the APIs I listed above one at a time and called the Directions API. Nothing worked, neither having a single API (Directions API) or having all of them.
The weird thing about Places API
A weird behavior I am getting is that I created a new API key and it worked without any restrictions. What is more weird is that I disabled Places API temporarily. I did this as I wanted to "refresh" my APIs. I read in another thread that the IP issue was resolved by disabling and re-enabling the Places API.So I turned it off but did not turn it on immediately. I used a new API key and clicking my location items yields to route info (I got the desired result).
Other restrictions (usage limit and billing)
I know that it is also not about the restriction of too many attempts on the Directions API. The documentation states that the limit is 50 requests per second. Besides, I did the "fast clicking of items" using the unrestricted API key and I always get a route info. Billing is also enabled on our project so that's not the issue either.
Stuck with an unrestricted key
Right now we are using an unrestricted key that is unacceptable. I wonder, why using an unrestricted key works perfectly and restricting it does not. I am sure I am missing a configuration but I have tried every possible combination that I can think of.
API keys restricted to your application's bundle ID won't work for backend web service requests such as Directions API. These API keys would only work for request made from Places SDK and Maps SDK for iOS. This is the reason why you are getting the error "This IP, site or mobile application is not authorized to use this API key. Request received from IP address {ip_address}, with empty referer".
According to Google Maps API key best practices, for API keys used for Web services sent directly from a mobile applications, you can do one or more of the following techniques to secure your API keys:
Use a proxy server. The proxy server provides a solid source for interacting with the appropriate Google Maps Platform API. Then restrict your API key with IP restrictions.
Obfuscate or encrypt the API key or signing secret. This complicates scraping of API keys and other private data directly from the application.
Use CA pinning or certificate pinning to verify the server resources are valid. CA pinning checks that a server's certificate was issued by a trusted certificate authority, and prevents Man-In-The-Middle attacks that could lead to a third party discovering your API key.

Google Map API Key in Directions (iOS app)

i want to use google map api for route between two location. in my IOS application. i try create public key for project and enable uses API in developer console. but i got this error: this ip site or mobile application is not authorized to use this api key IOS. after this error i try create API key for Key restriction for (IP addresses (web servers, cron jobs, etc.)) and set my ip address and then routing is work fine. but when i try this from other device again and again i get this error.
i should use this URL for routing :
let url = "https://maps.googleapis.com/maps/api/directions/json?origin=\(origin)&destination=\(destination)&mode=driving&key=APIKEY"
how can solve this problem for working my code in all devices.
The API key that you use with Google Maps web service (Directions API) supports an IP restriction as mentioned in the following document:
https://developers.google.com/maps/faq#using-google-maps-apis
The issue is that you cannot know the IP addresses of all devices where your application is installed.
You have the following options:
Use unrestricted API key. Note that API key requires HTTPS connection, so the API key won't be intercepted from the request itself, because the request is encrypted. So, in this case you should procure that the API key is not put directly in your source code. If you can read it from config or the environment, it might be feasible.
Create an intermediate server. Your iOS application should send requests to the intermediate server, intermediate server should send requests to Google and pass responses back to your app. In this case you can restrict an API key by IP address of your intermediate server.
I hope this helps!

Could not fetch Places - REQUEST_DENIED

I want to fetch places from google place api, I just download SPGooglePlacesAutocomplete & created new API Key enable place, direction & map api's from Google API Console still i am getting error alert.
Any help very much appreciated.
I assume you are using key which is made for iOS apps.But SPGooglePlacesAutocomplete might be using Google's public API to fetch the places list. So in that case you should use key for your browser apps. You can refer following link for more elaborated ans
REQUEST_DENIED when using the Google Places API
The Google Places API Web Service enforces a default limit of 1,000 free requests per 24 hour period.
The "status": "REQUEST_DENIED" is returned by the Google Places API Web Service when:
You have not activated the Google Places API Web Service in the Google API Console.
The key parameter is missing from your request. EX.
https://maps.googleapis.com/maps/api/place/add/json?key=YOUR_API_KEY
The key parameter does not match the your API key in the Google API Console.
Your API key has not been correctly set up in the Google API Console:
If you are using a browser-restricted API key, check that your
allowed referer(s) are correct.
If you are using a server-restricted API key, check that your allowed
IP(s) are correct.
API keys with Android or iOS restrictions are not supported. Please
use a generic (unrestricted) API key, or a key with browser or server
restrictions.
The request was not sent as an HTTPS request, HTTPS is required for all Google Places API Web Service requests.
The incorrect HTTP method was used to send the request:
All requests must be sent as a GET request except for Place Add.
All Place Add requests must be sent as a POST request.
You have to Create API Key from this link & from google console make sure you have enabled Google Place API.

How does Google Cloud Platform API key restriction for iOS apps work?

According to:
https://cloud.google.com/speech/docs/common/auth
We can create an API key to a GCP resource (e.g. Google Maps, Speech, Translate) restricted by "iOS apps" to a particular bundle ID. In principle this is great, but how does GCP actually implement this? How does GCP determine the client's bundle ID since only the client is only making standard HTTP requests to GCP -- presumably it's not reporting its bundle ID in the header?
I'd like to enable this for an API key but don't want to suddenly shut down my iOS client because somehow it's not reporting its bundle ID.
I think Google Translation API just identifies your app by value in request header key x-ios-bundle-identifier.
I tried using Postman to send a successful request with following parameters.
GCP API Key config
Postman request

How to hide the API key in my Electron application?

I'm building an Electron application that uses Google's YouTube Data API v3.
For accessing the API, I decided to use the standard API key (instead of OAuth, since I am not going to be accessing any personal data).
But the problem is, I cannot hide the API key in my app, and I also cannot use referrer restrictions (referrer restrictions allow you to filter which web sites can use your API key (by HTTP address)), since this is an Electron app. So basically, if someone looks at the source code (or even just at the developer tools), they can see the key, and use it freely.
Any advice on what to do? Thanks.
The only way to secure your API key for an application that does not require users to register or log in, is to place it behind a server proxy. So, when they start the app, the app reaches out to your server, the server then returns the API key so it only resides in the app in dynamic form, it is never visible to users.
However, this is still insecure if they use a packet sniffer or local proxy they can grab your token.
The most secure way to do this is to make all your API requests from a private server that your app has access to. So, the app makes no requests to Youtube, it only gets the data from your server.
Then, you can secure your app by signing API requests to your private server with a private key. For example, you could have a config file in the app with a private key that is sent in the header of every API request. Then, they only way to get your key would be to decompile your app, and then access that config file, then make API requests to your private server using the same private information. Then, to prevent malicious users, you can monitor traffic and set up request limits, like 1 request per second per app. Any app exceeding that limit could be black-listed as a DDOS attack or a malicious user.
The data flow would look something like this.
App -> Server (with Api Key) -> youtube (data) -> Server (data) -> App

Resources