How to hide your API keys and tokens in React to protect your application
Tags: react, typescript, webdev, programming
Published: 2023-01-17 15:23:43

## Using environment variables in Reactjs with Vite and nodejs

Have you ever noticed that some applications have API keys, tokens, or other sensitive credentials visible in their source code? or maybe your own applications?

Well, this can be dangerous and put the security of your services at risk.

API keys, tokens, and other sensitive credentials are used to authenticate and authorize access to services and APIs. If this data is exposed in your application’s source code, anyone who can see your code can access it and use it to perform unauthorized actions on your behalf.

Moreover, by exposing your credentials, you are allowing third parties to use them, which can affect the performance or quality of your services, or even perform attacks against them.

This tutorial will show us how to hide your API keys, tokens, and other sensitive credentials.

## How to hide sensitive data?
Some of the ways to do this are:

- Use environment variables
- Use a proxy server or a backend platform as a service (BaaS)
- Use a secure hosting platform

In this way, you can protect the security of your services and prevent them from being compromised.

Now, we will see how to hide sensitive credentials by building a small backend for our React application.

## Using Environment Variables in React with Vite

In this tutorial, we will add an [OpenWeather](https://openweathermap.org/) APY KEY as an environment variable.
Specifically, we will use the [weather API](https://openweathermap.org/current), which is a service that provides weather data, and after a certain number of requests, it starts charging for the requests, so we don’t want this API KEY to be available to the public.

To configure the environment variables in React with Vite we can follow the following steps:

1 — Create your React application with Vite. I will use TypeScript but you can use JavaScript if you wish.

2 — Create a `.env` file at the root of your project. This file should contain the environment variables you want to use in your application.

```bash
API_KEY=784dc6d4eXXXXXXXXb14460d3a356565
PORT=3001
```

Once we create our `.env` file we must not forget to attach it to the `.gitignore` file of git, otherwise, our `API KEY` will be exposed in the repository.

3— In Vite, to access the environment variables we need to access them via import.meta.env. This returns an object containing the available environment variables known to Vite.

The variables created must have the prefix `VITE_` or could be another prefix overwriting the default configuration option [envPrefix](https://vitejs.dev/config/shared-options.html#envprefix).

```typescript
const API_KEY = import.meta.env.VITE_API_KEY
```

4 — Now we will create a simple application that will fetch the Weather API to retrieve the temperature of a city.

```typescript
import { useEffect, useState } from "react"
import { ResponseWeather } from "../types"

const API_KEY = import.meta.env.VITE_API_KEY

import "./App.css"

function App() {
 const [weather, setWeather] = useState<ResponseWeather | null>(null)

 useEffect(() => {
   const options = {
     method: "GET",
     url: `https://api.openweathermap.org/data/2.5/weather?lat=43.7001&lon=-79.4163&appid=${API_KEY}`)
     headers: {
      "Content-Type": "application/json",
     },
  }

  axios.request(options).then(response => {
   setWeather(response.data)
  })

 }, [])

 if (!weather) return null

 return (
  <div className='App'>
   <h1>{weather?.name}</h1>
   <h2>{Math.floor(weather?.main.temp - 273.15)} °C</h2>
   <i>
     <img
       src={`http://openweathermap.org/img/wn/${weather?.weather[0].icon}@2x.png`}
       alt={weather?.weather[0].description}
      />
   </i>
   <p>{weather?.weather[0].main}</p>
  </div>
 )
}

export default App   
```

![Fetch Weather API](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4qiiv08x624yq2o0ehhm.png)

Now that we have hidden our `API KEY` with an environment variable and made sure that the .env file is not uploaded to the repository we have done half the work.

And why do we say this? Because our `API KEY` is still exposed in the final build, if we inspect our app in the browser we will find the value of the `API KEY`, so the only way to have this value completely hidden is to have it on the server side creating a backend service.

This backend will be in charge of making requests to the Openweather service and our client, that is, our React application will query this backend.

```bash
pnpm express cors dotenv axios
```

In this case that we use Typescript, we will need in addition

```bash
pnpm ts-node @types/express @types/cors @types/dotenv @types/node
```

- [express](https://expressjs.com/) to create a server
- [cors](https://github.com/expressjs/cors#readme) to enable resource sharing between different domains.
- [dotenv](https://github.com/motdotla/dotenv#readme) to load environment variables.
- [axios](https://axios-http.com/) to fetch data.

2 — We create a file called `api.ts` at the root of the project. We also take the opportunity to add a new command to `package.json` to boost our server.

```javascript
"scripts": {
  "server": "npx ts-node api.ts",
  ...
}
```

3 — We create the server and make available the endpoint that we will use from React.

```typescript
import express from "express"
import { Request, Response } from "express"
import * as dotenv from "dotenv"
import cors from "cors"
import axios from "axios"

dotenv.config()

const app = express()

app.use(cors())

app.get("/api/weather", (req: Request, res: Response) => {
 const options = {
  method: "GET",
  url: `https://api.openweathermap.org/data/2.5/weather?lat=43.7001&lon=-79.4163&appid=${process.env.VITE_API_KEY}`,
  headers: {
   "Content-Type": "application/json",
  },
 }

 axios
  .request(options)
  .then(response => {
   res.json(response.data)
  })
  .catch(err => {
   console.log(err)
  })
})

app.listen(process.env.VITE_PORT, () => console.log(`Server on port ${process.env.VITE_PORT || 3001}`))
```

Now that we have the backend service, our `API KEY` is completely hidden from the client. We could add more layers of security as we want for example, in the cors add only the domain where our app is hosted and only that domain can make requests.

4 — We start our server with the following command

```bash
pnpm run server
```

Finally, we just need to replace the URL of the request we make in React with the one we have in the backend. We no longer need to retrieve the `API KEY` in React.

```typescript
// Before
url: `https://api.openweathermap.org/data/2.5/weather?lat=43.7001&lon=-79.4163&appid=${API_KEY}`)

// After
 url: "http://localhost:3001/api/weather"
```

And that’s it! our application continues to work as usual only that we no longer have our API KEY exposed on the client side.

[Repo here.](https://github.com/ljaviertovar/data-safe-react)

## Conclusion

In conclusion, hiding sensitive data is something relatively easy, just follow the steps mentioned above and with that, we can avoid major risks and complications.

I hope this will help you to keep your projects safe.

---

**Read more:**

- [How to create reusable and customizable modals with React and TypeScript](https://dev.to/ljaviertovar/take-your-modals-to-the-next-level-how-to-create-reusable-and-customizable-modals-with-react-and-typescript-4555)

- [Why Should You Use Cleanup Functions in React’s useEffect Hook?](https://dev.to/ljaviertovar/why-should-you-use-cleanup-functions-in-reacts-useeffect-hook-2g2c)

Want to Connect?
Love connecting with friends all around the world on [Twitter](https://twitter.com/ljaviertovar).