Protect Your API Keys: Hide and Secure with Node JS
AD
Table of Contents
- Introduction
- Building a Node.js Relay
- Why hide API keys
- Setting up Node.js and npm
- Initializing npm and adding dependencies
- Creating the index.js file
- Creating Routes for the Relay
- Setting up the default route
- Adding routes for specific requests
- Fetching data from the Open Weather API
- Handling errors in the API
- Securing the Routes and Whitelisting
- Implementing rate limiting
- Adding CORS options and whitelisting
- Deploying the Node.js Relay
- Pushing to GitHub
- Hosting on glitch.com
- Conclusion
Building a Node.js Relay to Hide API Keys
In this article, we will explore how to build a Node.js relay that hides API keys. We will discuss the importance of hiding API keys and provide step-by-step instructions on setting up Node.js and npm. We will then guide You through initializing npm, adding dependencies, and creating the index.js file.
Introduction
API keys are crucial elements in accessing external services or data. However, exposing API keys in client-side code can be a significant security risk. To address this issue, we can hide API keys by creating a Node.js relay. This relay will act as an intermediary between the client-side code and the external API, keeping the API keys secure.
Building a Node.js Relay
Why hide API keys
Before we dive into the implementation details, let's understand why it is necessary to hide API keys. When client-side code, such as HTML, CSS, and JavaScript, is executed in the browser, it can be inspected by users. This means that any API keys embedded in the code can be easily accessed, leading to potential misuse or unauthorized access to the API.
Setting up Node.js and npm
To get started, we need to install Node.js and npm (Node Package Manager). Visit the official Node.js Website at nodejs.org and download the latest version for your operating system. The installation process is straightforward, and it also installs npm along with Node.js.
Initializing npm and adding dependencies
Once Node.js and npm are installed, we can proceed with initializing npm. Open your preferred code editor (e.g., Visual Studio Code) and Create an empty folder for your project. In the terminal, navigate to the project folder and run the command npm init -y. This command initializes npm with default values and creates a package.json file.
Next, we will add the necessary dependencies to our project using npm. In the terminal, run the command npm i dotenv express cors node-fetch. This installs the required packages: dotenv, express, cors, and node-fetch. The dotenv package allows us to load environment variables from a .env file, while the express package provides a framework for building APIs. The cors package is used for enabling Cross-Origin Resource Sharing, and node-fetch allows us to make HTTP requests in Node.js.
Creating the index.js file
Now that we have our dependencies installed, let's create the index.js file. This file will serve as the entry point for our Node.js relay. In your code editor, open the index.js file and add the following code:
require('dotenv').config();
const express = require('express');
const cors = require('cors');
const fetch = require('node-fetch');
const app = express();
const port = 3000;
app.use(express.json());
app.use(cors());
// Test route
app.get('/', (req, res) => {
res.json({ success: true, message: 'Hello, world!' });
});
app.listen(port, () => {
console.log(`App listening on port ${port}`);
});
In this code, we first import the necessary packages: dotenv for accessing environment variables, express for creating our API, cors for enabling Cross-Origin Resource Sharing, and node-fetch for making HTTP requests. We then create an instance of the express application and define the port on which our relay will listen.
To test that everything is set up correctly, we have added a simple test route that returns a JSON response with a success message.
Creating Routes for the Relay
Now that our initial setup is complete, let's move on to creating routes for our Node.js relay. These routes will allow us to relay requests from clients to external APIs and return the responses.
Setting up the default route
Before we get into specific routes, let's start by setting up a default route. This route will serve as the entry point for our relay and provide basic information about the relay.
To set up the default route, add the following code after the test route:
app.get('/', (req, res) => {
res.json({ success: true, message: 'Welcome to the Node.js Relay API!' });
});
In this code, we define a new GET route at the root endpoint ("/") and send a JSON response with a success message and a welcome message.
Adding routes for specific requests
Now, let's add routes for specific requests that will relay data from external APIs. For demonstration purposes, we will create a subdirectory called "weather" and set up routes to fetch weather data from the OpenWeather API.
Create a new folder named "weather" in your project directory. Inside the "weather" folder, create an index.js file. This file will hold the routes related to weather data.
In the index.js file under the "weather" folder, add the following code:
const express = require('express');
const router = express.Router();
const fetch = require('node-fetch');
// Test route
router.get('/', (req, res) => {
res.json({ success: true, message: 'This is the weather API section!' });
});
module.exports = router;
In this code, we import the necessary packages and create an instance of the Express Router. We then define a test route that returns a JSON response with a success message for the weather section of our API.
Fetching data from the OpenWeather API
Now that we have set up the test route, let's add a route to fetch weather data from the OpenWeather API. We will create a GET route that accepts a search query for the city name and returns the weather information for that city.
In the index.js file under the "weather" folder, add the following code below the test route:
router.get('/:searchText', async (req, res) => {
const { searchText } = req.params;
try {
const weatherStream = await fetch(
`https://api.openweathermap.org/data/2.5/weather?q=${searchText}&appid=${process.env.WEATHER_API_KEY}`
);
const weatherJson = await weatherStream.json();
res.json(weatherJson);
} catch (error) {
res.status(500).json({ error: error.stack });
}
});
In this code, we define a new GET route that accepts a dynamic parameter searchText in the URL. We then use the fetch function to make a request to the OpenWeather API, passing in the search text and the API key from our environment variables. Once we receive the weather data, we return it as a JSON response. If an error occurs during the process, we return a 500 status code and an error message.
Handling errors in the API
To handle potential errors when making requests to the OpenWeather API, we can utilize the built-in error handling in Express. In the index.js file under the "weather" folder, add the following code at the end:
router.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Internal Server Error' });
});
module.exports = router;
In this code, we create an error handler Middleware that catches any errors thrown during the request-response cycle. We log the error to the console and return a 500 status code with a generic error message.
Securing the Routes and Whitelisting
To ensure secure access to our routes and prevent unauthorized use, we will implement rate limiting and whitelist specific URLs that are allowed to access our API.
Implementing rate limiting
To implement rate limiting, we will use the express-rate-limit package. In the terminal, run the command npm i express-rate-limit to install this package.
In the index.js file, add the following code at the top, after the package imports:
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 1000, // 1 second
max: 1, // 1 request per second per IP
});
app.use(limiter);
In this code, we import the express-rate-limit package and create a rate limiter object. We set the windowMs option to 1000 (1 Second) and max option to 1, limiting each IP address to one request per second.
Adding CORS options and whitelisting
To allow only specific URLs to access our API, we need to set up CORS options and define a whitelist. In the index.js file, add the following code below the rate limiting setup:
const whitelist = ['http://localhost:3000', '127.0.0.1', 'http://localhost:5500'];
const corsOptions = {
origin: (origin, callback) => {
if (!origin || whitelist.indexOf(origin) !== -1) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
},
optionsSuccessStatus: 200,
};
app.use(cors(corsOptions));
In this code, we define a whitelist array containing the URLs that are allowed to access our routes. In our development setup, we add "http://localhost:3000", "127.0.0.1", and "http://localhost:5500" to the whitelist. You would replace these URLs with the actual URLs of your front-end applications.
We then create the corsOptions object, which checks if the requesting origin is in the whitelist. If it is, the callback function is called with null as the first parameter (indicating no error) and true as the second parameter (indicating the request is allowed). If the requesting origin is not in the whitelist, the callback function is called with a new Error object.
Deploying the Node.js Relay
With our Node.js relay fully developed and tested, We Are ready to deploy it and make it accessible to the public.
Pushing to GitHub
First, let's push our code to GitHub for version control and easy deployment. Initialize a new Git repository in your project folder using the command git init. Next, create a .gitignore file and add the line node_modules/ to ignore the node_modules folder.
Add the project files to the repository using the following commands:
git add .
git commit -m "Initial commit"
Create a new repository on GitHub and follow the instructions to push your code to that repository.
Hosting on glitch.com
To host our Node.js relay, we will use glitch.com. Glitch allows us to easily deploy our Node.js application for free.
- Visit glitch.com and sign up for an account (if you don't have one).
- Click on the "New Project" button and choose "Import from GitHub".
- Search for your repository and select it from the list.
- Glitch will import the code from your repository and set up the project for you.
After the import process is complete, you can preview your app by clicking on the "Show" button. Glitch provides a URL that allows you to access your live application.
Make sure to set up any required environment variables on Glitch, such as your API keys. You can do this by adding variables in the .env file in the Glitch editor.
Conclusion
In this article, we have learned how to build a Node.js relay to hide API keys. We discussed the importance of hiding API keys and provided step-by-step instructions for setting up Node.js, initializing npm, adding dependencies, and creating routes for the relay.
We covered how to fetch data from external APIs, handle errors, and secure our routes with rate limiting and whitelisting. Finally, we explored how to deploy our relay to GitHub and host it on glitch.com.
By implementing a Node.js relay, we can secure our API keys and ensure secure access to external APIs. This approach allows us to take AdVantage of the features and data provided by external APIs while keeping our keys and code Hidden from potential misuse or unauthorized access.