There's lots of general info about preventing API key leaks, but I'm having trouble finding proper procedure specifically for making an HTTP GET request with an API key as a parameter. Any user can easily inspect the request and grab an app's private API key as far as I can tell.
Is there any way to safely make GET requests? I'd use something other than GET if it was made available by the third party API. Might just be bad design.
Example from an app I'm working on. When I make a GET request to a third party API, my API key can easily be seen in the inspector:
Code:
const response = await fetch('https://www.someexampleimadeup.com?var=something&key=LOOKITSMYPRIVATEKEY'
Inspector:
CodePudding user response:
In this case, the key will not be leaked over the network because the request uses TLS (https://). This is because the querystring is entirely in the HTTP request, whose data is entirely sent across a secure connection.
However, it is never safe to use private API keys in a web client—with any kind of request, GET or otherwise. The frontend is rendered and run entirely on the machines of your users, so any information you put in that HTML or JavaScript can be seen. If the API you use only provides private API keys, then any requests you make must be done on your own server.
On the other hand, some API keys are meant to be used on the client. For example, consider the Google Maps API. In this, the only risk associated with having a visible API key is the fact that other users could use that key for their own websites and incur charges. Google mitigates this by allowing developers to specify allowed origins: that is, it limits what domains can use the key.
CodePudding user response:
You are right.
If you pass a private API key with your GET request initiated by client-side javascript, you are exposing the key. And no, there's no way around it if you want to do this client-side (if you are fetching the API from a javascript file that runs on the browser).
That's because by definition HTTP requests messages are composed of textual information encoded in ASCII (as properly explained in this MDN article). All HTTP requests of any protocol are always available to the user of the browser who initiated the request, even if you use HTTPS.
It's important to address that the simple fact of your private API key being present on client-side javascript code makes it insecure - public.
If running server-side javascript is an option for you, something like a Node.js backend server, you can fetch your server fetch("https://yourserver.com/resource")
, and then your server can fetch the API with the private key fetch('https://api.com/?api_key=XXXXX')
. Now your backend server is the middle man (or the black box) responsible for getting the API data without exposing the private key.
You won't be exposing the key because the user only knows about the GET request to your server and the data you choose to return. As well, as you have control over your server, you can choose not to expose your private API key by not serving the file in which it is written.
In Node.js webservers, you usually store your API key in a ".env" file PRIVATE_API_KEY=XXXXXXX
, which is not served. This file is then added to the rules present in .gitignore, to prevent it from being pushed to any public repository. With the help of a node package like dotenv, you can access it on your code as a property of the process.env object process.env.PRIVATE_API_KEY
(some examples in their npm page).