Reputation: 13902
I am trying to use the Google Places API from my javascript code.
(Assume that all the other things - api keys, enabling the API from google console, etc have already been done).
When I try to access the Places API directly from my javascript, it gives me a CORS error, which I presume is because my domain isn't whitelisted in the Places API.
To circumvent this, the suggested way is to use the Javascript Maps SDK. The SDK is not an npm module, it is a hosted JS file which is in the same domain as the Places API.
What I am trying to understand is how can this SDK which is written in Javascript, make calls to the Places API and does not get the CORS error.
Does it have something to do with the fact that the Maps SDK and the Places API are served from the same domain?
Shouldn't these api calls be executed in the context of my domain and blocked due to CORS?
Would it still work if the SDK was a npm package?
The api call that the SDK makes is not exactly same as the Places API, but it is on the same domain.
/maps/api/place/autocomplete/json?input=Ben&key=KEY
vs
/maps/places/api/js/AutocompleteService.GetPredicitons
I have tried the /maps/places/api/js/AutocompleteService.GetPredicitons call directly from my javascript but it also gives me CORS error.
Upvotes: 0
Views: 253
Reputation: 13902
TL;DR; the google sdk is using jsonp, by making the call using a script tag and specifying a callback. This is different from a XHR request which is blocked by same origin policy.
Explanation:
Where the script is hosted does not matter, as it is executed in the context of your domain, so any api calls that the browser makes would have the origin as your domain and not the domain where the script is hosted.
Which means, if the SDK is calling an endpoint from maps.googleapis.com/maps/... , which it in fact does, the request should be made with origin as my domain, and should give CORS error, but it was still returning data.
On further inspection, I discovered that the SDK is not making an xhr request (Which is blocked due to same origin policy) , rather it is creating a script tag and processing the response returned by the server. It is doing that using jsonp, by providing a callback in the url, so that the server sends the response wrapped in that callback, and once the script is downloaded and executed, it runs the function and sdk can now process the data.
Some points about security and general understanding:
The sdk needs to have an api key, which it sends along with every api call. So, if you download the sdk from the hosted url by passing in your key (which looks something like this: https://maps.googleapis.com/maps/api/js?key=KEY&libraries=places) and distribute it, you would basically be distributing the sdk script which has your key hardcoded inside it. (Of course, that does not have any specific security implications if you have restrictions setup on your api key, which you should do as your key is otherwise visible to your users in the network calls)
Even after I understood that the sdk is working using jsonp, and i was able to make the exact same api call, when I changed the query text for which I needed suggestions and changed nothing else (all other parameters were the same), the call still failed with a 403. This is because, the sdk seems to send a token in the parameter which is somehow derived from the query text. So, it is not easy to just bypass the sdk and create those calls yourself, as for that you would need to figure out the token generation algorithm.
On top of this, since I have enabled Referer only api key security, so anyway google would not allow any other referer to use my key, even if the key is visible in the networks tab for the users of my application.
Upvotes: 1