DEV Community

Cover image for Safeguarding Your API Keys in React
Ukwueze Onyedikachi
Ukwueze Onyedikachi

Posted on

Safeguarding Your API Keys in React

Years back, developers had to write all sorts of custom code to get different applications to communicate with each other. But, these days, Application Programming Interfaces (APIs) make it so much easier. APIs provide you with everything you need to interact with different applications smoothly and efficiently, most commonly where one application requests data from the other application.
While APIs offer numerous benefits, they also present a significant risk to your application security. That is why it is essential to learn about their vulnerabilities and how to protect them. In this article, we’ll delve into the wonderful world of API keys, discuss why you should protect your API keys, and look at the best ways to do so when using React.

Understanding API Keys: The Basics

Picture this: you're joining an exclusive club, and they hand you a secret passphrase. That's your API key! It's your golden ticket to unlock the treasures hidden within. Some keys are freebies, while others come with a price tag. And here's the kicker—most don't come with an expiration date, so safeguarding them is a must.

Why Hide API Keys?

Protecting your API keys is crucial for guaranteeing the security and integrity of your application. Here are some reasons why you ought to guard your API keys:
To prevent unauthorized API requests.
If someone obtains your API key, they can use it to make unauthorized requests, which could have serious ramifications, especially if your API contains sensitive data.
Financial insecurity.
Some APIs come with a financial cost. And if someone gains access to your API key and exceeds your budget requests, you may be stuck with a hefty bill which could cost you a ton and jeopardize your financial stability.
Data theft, manipulation, or deletion.
If a malicious person obtains access to your API key, they may steal, manipulate, delete, or use your data for their purposes.
Top Tips for Secretive API Key Management in React
Now that we've established the importance, let's talk strategies for keeping those keys under lock and key in your React app.

Using Environment Variables

Environment variables (env) are used to store information about the environment in which a program is running. It enables you to hide sensitive data from your application code, such as API keys, tokens, passwords, and just any other data you’d like to keep hidden from the public.
One of the most popular env packages you can use in your React application to hide sensitive data is the dotenv package. To get started:
Navigate to your react application directory and run the command below.

npm install dotenv --save

Enter fullscreen mode Exit fullscreen mode

Outside of the src folder in your project root directory, create a new file called

.env.

Image description

In your .env file, add the API key and its corresponding value in the following format:


// for CRA applications
REACT_APP_API_KEY = A1234567890B0987654321C ------ correct

// for Vite applications
VITE_SOME_KEY = 12345GATGAT34562CDRSCEEG3T  ------ correct

Enter fullscreen mode Exit fullscreen mode

Save the .env file and avoid sharing it publicly or committing it to version control.
You can now use the env object to access your environment variables in your React application.

// for CRA applications
'X-RapidAPI-Key':process.env.REACT_APP_API_KEY
// for Vite  applications
'X-RapidAPI-Key':import.meta.env.VITE_SOME_KEY

Enter fullscreen mode Exit fullscreen mode

Restart your application for the changes to take effect.
However, running your project on your local computer is only the beginning. At some point, you may need to upload your code to GitHub, which could potentially expose your .env file. So what to do then? You can consider using the .gitignore file to hide it.

*THE .gitignore FILE *
The .gitignore file is a text file that instructs Git to ignore files that have not yet been added to the repository when it’s pushed to the repo. To do this, add the .env to the .gitignore file before moving forward to staging your commits and pushing your code to GitHub.

// .gitignore
 dependencies
/node_modules
/.pnp
.pnp.js

 api keys
.env

Enter fullscreen mode Exit fullscreen mode

Keep in mind that at any time you decide to host your projects using any hosting platforms, like Vercel or Netlify, you are to provide your environment variables in your project settings and, soon after, redeploy your app to view the changes.

_BACK-END PROXY SERVER _
While environment variables can be an excellent way to protect your API keys, remember that they can still be compromised. Your keys can still be stolen if an attacker inspects your bundled code in the browser. So, what then can you do? Use a back-end proxy server.
A back-end proxy server acts as an intermediary between your client application and your server application. Instead of directly accessing the API from the front end, the front end sends a request to the back-end proxy server; the proxy server then retrieves the API key and makes the request to the API. Once the response is received, it removes the API key before returning the response to the front end. This way, your API key will never appear in your front-end code, and no one will be able to steal your API key by inspecting your code. Great! Now let’s take a look at how we can go about this:
Install necessary packages.
To get started, you need to install some packages such as Express, CORS, Axios, and Nodemon. To do this, navigate to the directory containing your React project and execute the following command:

`npm install` express cors axios nodemon

Enter fullscreen mode Exit fullscreen mode

Create a back-end server file.
In your project root directory, outside your srcfolder, create a JavaScript file that will contain all of your requests to the API.

Image description

Initialize dependencies and set up an endpoint.
In your backend server file, initialize the installed dependencies and set up an endpoint that will make a GET request to the third-party API and return the response data on the listened port. Here is an example code snippet:

// defining the server port
const port = 5000

// initializing installed dependencies
const express = require('express')
require('dotenv').config()
const axios = require('axios')
const app = express()
const cors = require('cors')
app.use(cors())

// listening for port 5000
app.listen(5000, ()=> console.log(`Server is running on ${port}` ))

// API request
app.get('/', (req,res)=>{    
    const options = {
        method: 'GET',
        url: 'https://wft-geo-db.p.rapidapi.com/v1/geo/adminDivisions',
        headers: {
            'X-RapidAPI-Key':process.env.REACT_APP_API_KEY,
            'X-RapidAPI-Host': 'wft-geo-db.p.rapidapi.com'
        }
   };
   `
    axios.request(options).then(function (response) {
        res.json(response.data);
    }).catch(function (error) {
        console.error(error);
    });
}

Enter fullscreen mode Exit fullscreen mode

Add a script tag in your package.json file that will run the back-end proxy server.

Image description

Kickstart the back-end server by running the command below and then, in this case, navigate to localhost:5000.

npm run start:backend

Enter fullscreen mode Exit fullscreen mode

Make a request to the backend server (http://localhost:5000/) from the front end instead of directly to the API endpoint. Here’s an illustration:

import axios from "axios";
import {useState, useEffect} from "react"

function App() {

  const [data, setData] = useState(null)

  useEffect(()=>{
    const options = {
      method: 'GET',
      url: "http://localhost:5000",
    }
    axios.request(options)
    .then(function (response) {
        setData(response.data.data)
    })
    .catch(function (error) {
        console.error(error);
    })  
  }, [])

  console.log(data)




 return (
    <main className="App">
    <h1>How to Create a Backend Proxy Server for Your API Keys</h1>
     {data && data.map((result)=>(
      <section key ={result.id}>
        <h4>Name:{result.name}</h4>
        <p>Population:{result.population}</p>
        <p>Region:{result.region}</p>
        <p>Latitude:{result.latitude}</p>
        <p>Longitude:{result.longitude}</p>
      </section>
    ))}
    </main>
  )
}
Enter fullscreen mode Exit fullscreen mode

export default App;

Okay, there you have it! By following these steps, you’ll be able to hide your API keys using a back-end proxy server in your React application.

KEY MANAGEMENT SERVICE
Even though environment variables and the back-end proxy server allow you to safely hide your API keys online, you are still not completely safe. You may have friends or foes around you who can access your computer and steal your API key. That is why data encryption is essential.
With a key management service provider, you can encrypt, use, and manage your API keys. There are tons of key management services that you can integrate into your React application, but to keep things simple, I will only mention a few:
AWS Secrets Manager
The AWS Secrets Manager is a secret management service provided by Amazon Web Services. It enables you to store and retrieve secrets such as database credentials, API keys, and other sensitive information programmatically via API calls to the AWS Secret Manager service. There are a ton of resources that can get you started in no time.
Google Cloud Secret Manager
The Google Cloud Secret Manager is a key management service provided and fully managed by the Google Cloud Platform. It is capable of storing, managing, and accessing sensitive data such as API keys, passwords, and certificates. The best part is that it seamlessly integrates with Google’s back-end-as-a-service features, making it an excellent choice for any developer looking for an easy solution.
Azure Key Vault
The Azure Key Vault is a cloud-based service provided by Microsoft Azure that allows you to seamlessly store and manage a variety of secrets, including passwords, API keys, database connection strings, and other sensitive data that you don’t want to expose directly in your application code.
There are more key management services available, and you can choose to go with any of the ones mentioned above. But if you want to go with a service that wasn’t mentioned, that’s perfectly fine as well.
Tips For Ensuring Security For Your API Keys
You have everything you need to keep your API keys and data secure. So, if you have existing projects in which you have accidentally exposed your API keys, don’t worry; I’ve put together some handy tips to help you identify and fix flaws in your React application codebase:

  • Review your existing codebase and identify any hardcoded API key that needs to be hidden.
  • Use environment variables with .gitignore to securely store your API keys. This will help to prevent accidental exposure of your keys and enable easier management across different environments.
  • To add an extra layer of security, consider using a back-end proxy server to protect your API keys, and, for advanced security needs, a key management tool would do the job. _ In Conclusion_ Protecting your API keys in a React application is critical to maintaining the security and integrity of your application. By implementing environment variables, using .gitignore, setting up back-end proxy servers, and leveraging key management services, you can effectively hide your API keys from prying eyes. Additionally, adopting advanced methods like RBAC, OAuth tokens, encryption, monitoring, and securing development environments further strengthens your security posture. Remember, safeguarding API keys is an ongoing effort that requires vigilance and proactive measures. By following these best practices and continuously improving your security strategies, you can ensure that your application remains safe, secure, and resilient against potential threats.

Top comments (0)