Google Map API Key in Directions (iOS app) - ios

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!

Related

UWP app - Migrate your impacted OAuth Loopback IP Address

I recently received an email from Google saying "Migrate your impacted OAuth Loopback IP Address clients to an alternative method". I have a UWP app that creates a google sso login, The OAuth 2.0 Client IDs type is "ios" (I used this sample from Google: https://github.com/googlesamples/oauth-apps-for-windows/blob/master/OAuthUniversalApp/README.md).
I read the migration guide from Google: https://developers.google.com/identity/protocols/oauth2/resources/loopback-migration.
And they are saying that the redirect_uri parameter has any of the following values:
redirect_uri=http://127.0.0.1: e.g. redirect_uri=http://127.0.0.1:3000
redirect_uri=http://[::1]: e.g. redirect_uri=http://[::1]:3000
redirect_uri=http://localhost: e.g. redirect_uri=http://localhost:3000
My app doesn't use any of those redirect_uri but still, I got those mail to migrate Loopback IP Address.
Also, Google posted this guide:https://developers.googleblog.com/2022/02/making-oauth-flows-safer.html for migrating and they did not mention the UWP app.
Am I missing something? and if I don't why did I get this email in the first place?

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.

How to access RestFul Apis through Appium-TestNG framework in AWS-Device Farm?

We have created our automation framework using Appium-TestNG in which we are accessing our backend servers through RestFul Apis externally. The backend server is also based on AWS and has whitelisted the device farm IPs. When we are executing the tests locally its working fine but when we execute it on AWS Device Farm, it is giving ‘Socket Exception’ when trying to access the backend servers via our apis.
Can anyone give us a solution of how to access external Rest APIS via Device Farm?
The IP range that's in the FAQ of Device Farm point to the devices but not the device host. The device host could have a wide range of IPs but there are two ways(that I've found so far) to get around this issue in theory:
Use the private offering from Device Farm.
If you have access to the private offering for Device Farm, you're able to use the VPC integration with both the devices and the device host. So there shouldn't be any white-listing needed using this method.
Use API Gateway's private VPC integration and call this API from the tests
When using the public offering(metered and unmetered options) we should be able to take advantage of API Gateway's VPC integration. Using an private NLB in the same VPC as the REST API we can create a VPC link. The ending architecture I believe should look like this:
Then we can secure the API using an API key or custom authorizers. So then we can call this API which links to the private REST API from the device host.
Note: This might not be the best workaround depending on the use-case as then the device host will have access to the API key.
Additionally(I know you didn't ask this but wanted to link to it anyway), the easiest way I've found so far to develop REST API calls is to use Postman to make a successful call to the REST API. Then use the code snippet feature to make the same calls in the support languages from postman.
Hope that helps
-James

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