A dead easy proxy server to remove your front-end API keys.
- How it works
- Deploying your own proxy server to Heroku
- Test it with the Open Weather Api
- Contributing
- Show your support
- Acknowledgments
- License
Once you have it setup and deployed, redirect your API calls to the proxy server, this will handle the requests to the API service using your authentication method and give you back the response if you are an allowed origin.
You are able to set up as many API services as you like by providing different endpoints to each one of them. Take a look at the config to get an idea on how to setup your API services.
For example, let say you are using the Open Weather Api, so in your code you have a request that looks something like this:
const endpoint = 'https://api.openweathermap.org/data/2.5/weather'
fetch(`${endpoint}?q=${city}&units=${units}&appid=${apiKey}`)
.then(response => response.json)
.then(json => handleData(json))
π Notice the API key is included in the request: &appid=${apiKey}
π’.
After setting your proxy server you can call your new endpoint without the API key:
const endpoint = 'https://calm-horse-55245.herokuapp.com/weather'
fetch(`${endpoint}?q=${city}&units=${units}`)
.then(response => response.json)
.then(json => handleData(json))
π Now you can remove the API key from your request: π.
Once the proxy gets the request, it will include your API key and pass it to the Open Weather Api, and return to you with the response from the API if you are an allowed origin.
To get your proxy server up and running:
git clone https://github.com/mauriciorobayo/api-key-proxy-server.git
cd api-key-proxy-heroku
heroku create
Include your API keys on the Heroku app. On the dashboard go to Settings
and lookup for the Config Vars
section. Copy and paste your API keys there using the same variable name you are using to retrieve it on each proxy service on the config.ts file. For example, in the case of the [Open Weather Api proxy] that is included with the code, the variable name is WEATHER_API_KEY
.
You can include all the API services you want using the config.ts
file which exports an object with the following options:
allowedDomains: An array of domains you want to allow to make calls to the proxy server. All the domains not listed here will be rejected with a cors
error.
Do not include pathnames:
- Wrong:
https://example.com/some-path
β - Right:
https://example.com
β
Do not include trailing slash:
- Wrong:
https://example.com/
β - Right:
https://example.com
β
Example:
allowedDomains: ['https://www.mauriciorobayo.com', 'https://example.com']
proxies: An array with the configuration options for each API service. The config file included provides configurations for Open Weather API, the ipinfo API, and the GitHub API. You can remove or add as many as you need:
[
{
route: '/weather',
allowedMethods: ['GET'],
target: 'https://api.openweathermap.org/data/2.5/weather',
queryparams: {
appid: process.env.WEATHER_API_KEY,
},
},
{
route: '/ipinfo',
allowedMethods: ['GET'],
target: 'https://ipinfo.io/',
queryparams: {
token: process.env.IPINFO_TOKEN,
},
},
{
route: '/github',
allowedMethods: ['GET'],
target: 'https://api.github.com',
headers: {
Accept: 'application/vnd.github.v3+json',
},
auth: `${process.env.GITHUB_USERNAME}:${process.env.GITHUB_TOKEN}`,
},
],
The following are the options for each proxy config:
allowedDomains: You can include specific allowed domains just for a specific proxy.
route: The path on the proxy server. For example, if you set it to '/weather'
, then you will access that API service through that path on your proxy server: https://your-proxy-server.heroku.app/weather
.
allowedMethods: An array of methods the server will proxy to the API service. It defaults to 'GET'
.
target: The API endpoint that's going to be proxied by the proxy server. All request made to the route
on the proxy server will be proxied to the target
endpoint.
headers: An object with the headers that will be added to the request made to the proxy server.
auth: Basic authentication, for example: 'user:password' to compute an Authorization header.
queryparams: Additional query params to be added to the request made to the proxy.
git commit -am"Update proxy settings"
git push heroku
Finally, you can use your Proxy server to redirect the requests from your front end code. For example:
// Original request
const apiService = 'https://api.openweathermap.org/data/2.5/weather'
fetch(`${apiService}?q=${city}&units=${units}&appid=${apiKey}`)
.then(response => response.json())
.then(json => handleData(json))
// Request using your proxy
const apiProxy = 'https://calm-horse-55245.herokuapp.com/weather'
fetch(`${apiProxy}?q=${city}&units=${units}`)
.then(response => response.json())
.then(json => handleData(json))
The code already includes three API services you can test drive it:
To test it on your local machine or for development purposes:
git clone https://github.com/MauricioRobayo/api-key-proxy-heroku.git
cd api-key-proxy-heroku
npm install
You don't need to specify the allowed domains when testing on your local machine in the development environment. By default, all domains are whitelisted so you don't need to figure out exactly which domain and port your browser or api client uses to make requests.
Copy the .env.sample
file included in the root of the repo to a file named .env
also in the root of the repo, and include your API keys there.
Start the development server with npm run start:dev
.
Now you can test drive your proxy server on your local machine for development:
http://localhost:5000/weather
will include theWEATHER_API_KEY
key from your.env
file and forward the requests to the Open Weather Api.http://localhost:5000/ipinfo
will include theIPINFO_API_KEY
key from your.env
file and forward the requests to the IPinfo Api.http://localhost:5000/github
will include the basic authentication from your.env
file and forward the requests to the GitHub Api.
All contributions are welcome!
Give it a βοΈ if you like this project!
All the heavy lifting is done by the http-proxy-middleware module.
The server is handled by Express.
Github: @mauriciorobayo Twitter: @mauriciorobayo_ LinkedIn: @mauriciorobayo
This project is MIT licensed.