Google places API - 'REQUEST_DENIED' when using server-side proxy on EC2 - proxy

I'm stuck trying to get an API call to Google Places working. I'm using a server-side PHP proxy for the request - not because I want to, but because it's part of JQuery-POI-Mapper.
The server I'm using is an Amazon EC2 server without a static IP address. I'm out of stactic IP addresses at the moment, but I'll take the time to request more if people think that's the problem. I identified the current public IP address of my EC2 server by running this command on the server:
curl http://169.254.169.254/latest/meta-data/public-ipv4
Next, I went to https://code.google.com/apis/console and created a new API key. I selected a server-side API key and used my EC2 server's public IP address.
Under the services tab, I enabled every related API I could think of, including:
Google Maps API v2
Google Maps API v3
Google Maps Gelolocation API
Places API
Static Maps API
Here's a screen capture of my Services:
The proxy code running on the EC2 server is part of a commercial package, so I shouldn't post the entire code, but it's very short, and the important part is:
$json = file_get_contents($url);
The $url variable in my case was:
https://maps.googleapis.com/maps/api/place/search/json?location=-37.7133771,145.14891620000003&radius=2000&types=bakery&sensor=false&key=AIzaSyCCUV...
The response I get is:
{
"html_attributions" : [],
"results" : [],
"status" : "REQUEST_DENIED"
}
I checked to see if I had gone over my quota already, but everything looks OK. What's interesting is that Google is showing that I had made requests to the Places API today, so Google definitely knows that the requests are coming from me.
Here's a screen capture of my API Traffic Report, which is all from testing:
Any advice would be much appreciated.
Thanks,
Bret

You need a Static IP address to successfully use IP Locking with a Server API Key.

Related

Google Indexing API test environment?

I'm implementing the Google Indexing API for some job posts, and I have it working in "production" (sending url's that are preceded with my public domain i.e. "jobs.myproduction.com") but I can't figure out how to test it in any QA or integration environment. The domains of the links wouldn't be my verified domain (the public one) but rather something like "box1.qa.myproduction.com" and those URLs aren't even publicly accessible.
In other APIs, we'd have test keys and a test endpoint, we'd deploy those values into configuration tables all the way up the line so that throughout testing we're hitting a test API endpoint with a test key and we can see it working while NOT publishing test data to a production system. But Google doesn't seem to have that. It's either do it in production with production values or get constant failures.
Right now, on my dev machine, I have "localhost" urls for my job postings, those get rejected from the API call for what looks like the fact that it's "localhost". If I change it to a dummy domain "jobs.mytest.com", I get a 403 FORBIDDEN, presumably because I'm not a validated owner of the "jobs.mytest.com" domain.
I CAN get a 200 out of google if I use a subdomain above my verified domain. So I have verified domain "jobs.myproduction.com", if I send the url as "https://test.jobs.myproduction.com/jobs/whateverId" I can get a 200 back. But:
I don't know where that's going (the domain isn't valid so I assume google won't list it)
I wouldn't put it above Google to somehow ding me for submitting bad URLs, and
This doesn't seem to be the right way to do this at all.
Does anyone have a suggestion on how to get around this? Am I missing something in the Google API dashboard for test accounts?

getting REQUEST_DENIED ("This service requires an API key.") but no error in the API console

I just added Google Places API Web Service to my project, added an API key (unrestricted, for testing) and I am copy pasting requests from the docs to try things out, for example:
curl https://maps.googleapis.com/maps/api/place/details/json?placeid=ChIJN1t_tDeuEmsRUsoyG83frY4&key=my_new_key
I only get Request Denied ("This service requires an API key."), but in the API console I do not see any errors. The key is really in the curl command line in my sample, the API is enabled in the console, the key is valid and not restricted. I cannot find a reason why this should not work?
Here are few things you could try...
API key is for the application but you should authorize that application in google before using it.
Check your API key again and see if theres any encoding required before using it.
Enable API from your google account.
See if theres any restriction on your API key for example :
Under Accept requests from these server IP addresses, enter the IP
addresses from which your key is to be accepted, one per line. You
may also enter a subnet using CIDR notation (e.g. 192.168.0.0/22).
Hope this helps..
Try this link.... very helpful
REQUEST DENIED with Google Places API KEY for Server Web used in an Android application

Instagram Subscription Callback using AWS API Gateway - Invalid SSL certificate

We're trying to set up an instagram app and have worked our way through the process. We've now got stuck when trying to create a subscription.
We have our app hosted on AWS API Gateway, which can only be deployed with HTTPS endpoints (it does not support unencrypted connections).
When we do the POST to get instagram to subscribe to a user using the following:
curl -F 'client_id=CLIENT-ID' \
-F 'client_secret=CLIENT-SECRET' \
-F 'object=user' \
-F 'aspect=media' \
-F 'verify_token=myVerifyToken' \
-F 'callback_url=https://YOUR-CALLBACK/URL' \
https://api.instagram.com/v1/subscriptions/
then we get the following error:
{
"meta": {
"error_type": "APISubscriptionError",
"code": 400,
"error_message": "Invalid response"
}
}
This happens whether we use our own HTTPS certificate that we have registered with API Gateway, or whether we use the stock AWS URL (https://xxxx.execute-api.us-east-1.amazonaws.com) as the callback (which also has a valid HTTPS certificate). I have verified that the certificates are 'good' using SSLLabs (they both get an A result). Our code NEVER gets called (so it's not the return of the hub.challenge parameter that's the problem. Instagram seems to reject the HTTPS certificate when initiating the connection.
Interestingly, if we use the same certificate that we use with AWS API Gateway on a normal machine (EC2 instance) and change the DNS records to point to this server, then it all works as expected and the subscription works.
Has anyone got Instagram Subscriptions working when using AWS API Gateway?
I came across this post and felt deceived by the current answer given that API gateway can still be used despite instagram's api not accepting the SNI.
"Instagram apps will not work if hosted on API Gateway unfortunately until Instagram upgrades their version of Python." is not true.
All you need to do is put a CloudFront instance in front of the api gateway and it will work fine without needing an expensive SSL cert or anything.
I included screenshots of my config so that it may help someone in the future.
Here is the first configuration screenshot
Behavior Settings
Origin Settings
We contacted Instagram about this. The version of Python (or their libraries) that Instagram uses does not support SNI which API Gateway uses (http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-custom-domains.html) so Instagram apps will not work if hosted on API Gateway unfortunately until Instagram upgrades their version of Python.
As Garrett points out below, whilst Instagram cannot post directly to API Gateway, you can put a cloudfront distribution in front of your API Gateway endpoints and let Instagram point to that. This will work.
To verify if this is a API Gateway issue have you tried to issue the same challenge request that Instagram is making to your API endpoint directly ?
If you haven't already, you should also try to enable CloudWatch logging on your API stage to debug the call.

How to access the Books API from a web application hosted on Microsoft Azure?

I have built a simple enough web application that uses the Google Books API to retrieve volume information for an ISBN the user provided. The application uses the official C# library. Requests are authorized by means of an API Key.
When running the app on my local machine I access the service with a German IP address and everything is fine. When accessing the Books API from Microsoft Azure however I get the following error:
Google.Apis.Requests.RequestError
Cannot determine user location for geographically restricted operation. [403]
Errors [
Message[Cannot determine user location for geographically restricted operation.]
Location[ - ]
Reason[unknownLocation]
Domain[global]
]
Does anyone know how to access the Google Books API from a web application hosted in Microsoft Azure?
country=us URL param solved this for me, mentioned in this github project, but not documented in the volumes list route of course
This blog says you can also use x-forwarded-for, I didn't try that
Ok I have no idea if this will work. But you can supply the ip address in your request. This may or may not work if it doesn't let me know and I will delete this.
var bookService = new BooksService(new BaseClientService.Initializer()
{
ApiKey = "xxxx",
ApplicationName = "BooksService Authentication Sample",
});
var request = bookService.Bookshelves.List("user");
request.UserIp = ""; //<-- find an ip address to feed it
var result = request.Execute();
The thing is Google normally takes the IP address the request is coming from. I wonder why it cant pick up a geo location from the IP address Azure is sending the request from.

Youtube data API refusing my server side requests

I'm developing an application that uses the Youtube Data API from the server (with node.js) so I have my server side credential key already set up but when I try to get data is always refusing my requests with this message.
Access Not Configured. The API is not enabled for your project, or there is a per-IP or per-Referer restriction configured on your API key and the request does not match these restrictions. Please use the Google Developers Console to update your configuration.
I've my app hosted in Heroku with the add-on Quote Guard Static that gives me two static IP's that I have whitelisted in the Credentials section of the google developers console. I also have the app hosted in modulus.io and whitelisted the IP range 54.0.0.0/8 that is what they gave me for their AWS region... Any of both deployments are working only in my local machine with my home external IP whitelisted.
The funny thing is that yesterday 15 minutes approximately after I whitelisted the 54.0.0.0/8 range, the app API started working in my Heroku host, but today it stopped again (this might be because it has changed to another IP inside their AWS region or something...).
Is there any way to check what IP is doing the requests to the Youtube data api? I can see in the developers console the request reaching the API and been rejected as "errors" at least I know that their are getting the requests...
Any ideas??
Thanks
EDIT:
Partially solved. See my answer below.
There's a simple service I found that returns your public IP:
http://api.ipify.org?format=json
You could add a route to your application that you can hit from your browser. The route handler then makes a request to this service and returns the result. You could then periodically check what your app's actual public IP is and adjust whitelist accordingly.
// Example express + request
app.get('/ip', function(req, res) {
request({ uri: 'http://api.ipify.org?format=json' }, function(err, response, body) {
res.send(body);
});
});
The problem with the app hosted in Modulus.io is solved now. The app was running by default in Joyent servers but I changed it to the Amazon AWS region and with the IP range 54.0.0.0/8 whitelisted google is accepting all my requests to the API.
Nevertheless, the app in heroku still not working but as is working in one service I'm going to stop investigating in the other one.

Resources