I want to use distance matrix by google. When I use postman for checking my URL, it works fine, it returns correct JSON. When I do the same thing in my android app, I receive request denied. I'm not restricitng my key, i do not autorize it, I want it to be public and I want to use it everywhere if possible. There are post 5 years old saying that I might be using web browser Api key, but I cannot find specific, android app manual for android api key generator. What I am doing wrong?
request denied
Another thing, I cannot change anything in my account, but I dont think these options matter since they are optional.
Failed to save
I'm using Retrofit:
#GET("maps/api/distancematrix/json")
Call<DistanceResponseModel> getDistanceModel2(#Query("origins") String origins,
#Query("destinations") String destinations,
#Query("key") String key);
I've activated APi in CloudConsole
i'm adding key to the request
APIs are no restricted or unauthorized
I also added key to manifest and gradle with THIS manual
I was using http instead of https in my serivce generator. So yeah, lol.
Related
Twitter login isn't working anymore on my android project and I have figured out that it's because I have restricted my API keys in Google cloud. By default, twitter login makes use of an https request https://<project_name>.firebaseapp.com/__/auth/handler....apiKey=...&providerId=twitter.com&sessionId etc where apiKey is the API key in my google-services.json. Given that I have restricted the API Key to my Android app package name, https requests for twitter login return an error. If I manually edit the url and put the Browser API key, it works fine but this is obviously not a practical solution for production.
Is there a way to tell AuthUI.IdpConfig.TwitterBuilder() to use a specific API Key so that I can pass the default Browser API key.
I have tried to manually edit google-services.json to add the Browser API Key and this fixes the Twitter Log in issue and breaks other calls to the server.
One work around is to have an extra key that your end users can have who you trust and check this via query params.
Const BrowserAPIKey = 'realKeyhere';
Create a unique key and save it as a constant in the function you call Twitter login.
Under the key variable call any URL and append a query param like so e.g. firebaseauth.com/twitter?key=123 and then pluck out the key by calling req.body.key so if you requested the API with a param called key. I.e. save this in another const e.g. const enteredKey = req.body.key. We expect 123 to be the resolved key if things are to work
Check if trusted clients got key right and release Browser API Key based on result:
If enteredKey = 123
// Call Twitter login api with real browser key
https://<project_name>.firebaseapp.com/__/auth/handler....apiKey=BrowserAPIKey...&providerId=twitter.com&sessionId
Assumptions:
This API accepts the browser key via a param called browserkey and spelt exactly that way
The BrowserAPIKey when in step 3 above contains the actual key that clients need to login with
I got in touch with Firebase support and this is expected behaviour if you restrict your API. In short, the API restriction for Android application is searching for package name and SHA-1 headers, the Twitter sign-in flow is based on a browser, so the headers are not sent, also there is no way to pass the headers through the browser.
The best approach would be using API restrictions (which APIs can my API be used for) rather than platform restrictions (which platforms can use this API key).
I've made an app that has a search function that is set to search from a custom Google search I made (using their Custom Search service). This doesn't have a Java library, so I'm using Retrofit to request using the REST API (https://developers.google.com/custom-search/json-api/v1/using_rest), however I've run into a problem:
Retrofit is working fine, but the request always returns a 400 error with the following information:
"domain": "usageLimits", "reason": "keyInvalid"
The API key I use in the request is the Android application key for my project in Google dev console. I assume this doesn't work however because Retrofit doesn't let Google know that I'm sending the request from my app?
What are the possible fixes for this situation?
Thanks.
EDIT: I've confirmed that my APK is signed with the correct keys, and I triplequadruplequintuple-everything checked the SHA1 used to generate the apikey. I've generated a new api key about 3 or 4 times to see if that fixes it.
EDIT2:
I got it to work!
You don't make an Android API key (it does not work with this), you make a browser API key, in which you set the allowed referers to all (potentially dangerous).
You use that API key to request using Retrofit. I feel like this should be noted by Google: no doubt many would assume Android app? -> Android API key - but that is only the case when Google has made a library for the API.
Sounds like you simply need to pass the key as a query parameter into your rest interface.
As an example, if you wanted to execute this GET command below
GET https://www.googleapis.com/customsearch/v1?key=INSERT_YOUR_API_KEY&cx=017576662512468239146:omuauf_lfve&q=lectures
Then you interface would be declared like so
public interface RestApi {
GET ("/customsearch/v1")
Response customSearch(#Query("key") String key, #Query("cx") String cx, #Query("q") String query);
}
Then you can execute the call like so
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("https://www.googleapis.com")
.build();
RestApi restApi = restAdapter.create(RestApi.class)
restApi.customSearch("INSERT_YOUR_API_KEY", "017576662512468239146:omuauf_lfve", "lectures");
Now don't forget to replace the INSERT_YOUR_API_KEY with your key that you've generated from the Google Dev Console.
I have been doing a lot of research recently on securing my app engine. Currently, I've been reading through the question below and the links in that question:
How do I restrict Google App Engine Endpoints API access to only my Android applications?
However, it doesn't answer my problem. My question is similar to the question above, restricting access to my endpoint API to only my app. The guy seemed to have got it working when he inputs a correct email into the credentials.
My question is if I can achieve the same results without having to input any credentials. I want it so that only my app can use my endpoint API so to prevent other apps from abusing it and using up my quota. I already got a client id for my android application, and have placed it within my #API annotation. To test if it worked, I made a random value for the client id in the #API notation of another api class. However, my app was still able to use methods from both class. Any help?
-Edit-
From reading from the docs and researching further, the endpoint way of authorizing apps is by authenticating the user and for my API to check if user is null. My question is that in the process of authenticating the user, is Google somehow able to read my app's SHA1 fingerprint and authorize it to its list of client ids? If so, how can I replicate this process in my endpoint so that I check the SHA1 fingerprint of the app making the request and compare it to a set value? I don't understand the mechanics behind the endpoints very well, so correct me if I am understanding this wrong.
If the android app has access, then the user has access. A motivated party has many options for inspecting your protocol, including putting the device behind transparent proxy or simply running the app through a debugger. I do suggest running your app through ProGuard before publishing, as this will make the process [a bit] more difficult.
Ultimately, you'll need to make your appengine API robust against untrusted parties. This is simply the state of the web.
How you can protect your endpoint API is described here: http://android-developers.blogspot.com/2013/01/verifying-back-end-calls-from-android.html
The secret is that you request a token from Google Play using the following scope: audience:server:client_id:9414861317621.apps.googleusercontent.com where 9414861317621.apps.googleusercontent.com is your ClientId.
Google Play will look up the id at your endpoints app and return a Google-signed JSON Web Token if it finds the id. Then you pass that id in with your request. Above article says you should pass it in with the body. I would possibly rather add another parameter for that because otherwise you can't pass your own entities anymore. Anyway, your server backend receives the token, and you ask Google as described if it is authentic, before you process the API request.
If you pass in the token using an extra parameter, you can catch it on the server side by adding HttpServletRequest to your endpoint signature and then using request.getHeader("Yourname") to read it out. Make sure you never add the parameter as a URL parameter as it may be logged somewhere.
public void endpointmethod(
// ... your own parameters here
final HttpServletRequest request
) throws ServiceException, OAuthRequestException {
request.getHeader("YourHeaderName") // read your header here, authenticate it with Google and raise OAuthRequestException if it can't be validated
On the Android side you can pass in your token when you build the endpoint api, like this, so you don't have to do it with each and every request:
Yourapiname.Builder builder = new Yourapiname.Builder(AndroidHttp.newCompatibleTransport(), getJsonFactory(), new HttpRequestInitializer() {
public void initialize(HttpRequest httpRequest) {
httpRequest.setHeader(...);
}})
Hope this helps you make your endpoints API secure. It should.
I'm having a difficult time getting a valid autocomplete response from the Google Places API. I'm using code based on [their example}(https://developers.google.com/places/training/autocomplete-android) (which, interestingly is using a seemingly invalid country code of "uk").
I have enabled Places API in my Google Code Console.
My API key was generated when I first enabled the Maps API a couple of weeks ago, and the MapFragment I'm using is working perfectly, so I have no reason to suspect that the API key is invalid.
The URL I'm using is https://maps.googleapis.com/maps/api/place/autocomplete/json?input=New+York&sensor=false&key=my_valid_api_key&components=country:us
I always get {"status":"REQUEST_DENIED","predictions":[]} as my response.
I have verified multiple times that my url is formed correctly and adheres to the requirements of the Places API autocomplete endpoint, yet I do not get the response I'm expecting.
I have seen a number of suggestions of how to fix this on SO and elsewhere, but none of them have worked for me (i.e.-using http instead of https, use port 443, etc.) I have tried these in all reasonable combinations with no change in the response.
Please help me find what I'm doing wrong.
I tried the URL you provided with my key and it returned the expected results. I suspect you are using an Android key instead of a Browser key. Try creating and using a Browser key (under "Simple API Access").
Use the server or browser key instead of the iOS key. Keep the refers field blank to allow all refers.
Here is a sample project which does the same :https://github.com/manishnath/Autocomplete
Try this way https://maps.googleapis.com/maps/api/place/autocomplete/json?input=Aus&types=geocode&language=eng&key=your_APIKEY
also refer this like
http://codetheory.in/google-place-api-autocomplete-service-in-android-application/
REQUEST_DENIED indicates that your request was denied, generally because of lack of a sensor parameter.try this
https://maps.googleapis.com/maps/api/place/autocomplete/json?input=Vict&types=geocode&language=fr&sensor=true&key=AddYourOwnKeyHere
I'm creating app that use autocomplete places google api.
And I don't know what is wrong but all the time I got responses like:
{
"predictions" : [],
"status" : "REQUEST_DENIED"
}
I send req : https://maps.googleapis.com/maps/api/place/autocomplete/json?input=Paris&types=geocode&language=fr&sensor=true&key=mykey
Documentation says :
REQUEST_DENIED indicates that your request was denied, generally because of lack of a sensor parameter.
I have sensor parameter, maybe it is something with api key.
Is there any page where can I get google's log :), to see why I got REQUEST_DENIED?
I use api key from :
http://code.google.com/intl/pl-PL/android/maps-api-signup.html
Maybe I have to get an api key from somewhere else.
You should be able to view your API Key by going to the API Console first:
https://code.google.com/apis/console
If you haven't yet, you will need to create a new "Project" and then enable the Predictions services first by using the On/Off switch.
Please post your results, I have a similar problem with getting the REQUEST_DENIED response, but I've already got the API key and I'm using the sensor parameter like their documentation states.
It is frustrating that Google doesn't give any sort of response code along with REQUEST_DENIED so you can see why it's denying it. This will be difficult to support and troubleshoot in a production environment if this randomly goes out without providing any details as to why.
Update:
I just found this works for me now, but only after changing my requests to GET requests instead of POST. For reasons unknown, Google returns REQUEST_DENIED for POST requests but allows the same request via GET. A quick test for you to see if this is your problem would be to put the URL together with your API key and other parameters and try it through your browser instead. If that works then just rewrite your Android code to use GET instead of POST and you should be all set.
It was solved for me when I exchanged the API key. I was using the one under Android device, I changed it to the one "Key for browser apps (with referers)" and it worked for me although I'm using Android Device.
I recommend using .getJson() to get an error message along with your response to know what is exactly wrong.
For my case in flutter: I used googlePlace!.autocomplete.getJson(value);
and i got the following response.
{ "error_message" : "You must enable Billing on the Google Cloud Project at https://console.cloud.google.com/project/_/billing/enable Learn more at https://developers.google.com/maps/gmp-get-started", "predictions" : [], "status" : "REQUEST_DENIED" }
That's the wrong API key. Follow the steps here to get the right one.
Make sure you API keys are generated correctly and that you have enabled the necessary APIS.
In my case, when designing iOS application - I need to enable Google Maps SDK for iOS, Google Places API for iOS
And most importantly, and without being mentioned by Google (in any other place as well) enable Google Places API Web Service.
With this, I ended a 2 day search for my pesky problem.
And, of course, make sure you use Key for server applications