How to Secure Your API Keys in Frontend Apps with Netlify Functions

As a full-stack developer, one of your top priorities is ensuring the security of your application and protecting sensitive data. A common challenge is figuring out how to securely use third-party APIs that require API keys or other credentials, especially when building frontend applications.

In this in-depth guide, we‘ll explore the risks of exposing API keys, and walk through a step-by-step tutorial on using Netlify Functions to hide your API keys and secure your frontend apps. We‘ll also cover best practices, alternatives, and expert tips for managing API keys across the stack.

The Dangers of Exposed API Keys

API keys are like the password to your third-party services. If an attacker gets ahold of your API key, they could make unauthorized requests to the API, potentially:

  • Accessing and stealing sensitive user data
  • Making expensive requests that rack up your API bill
  • Abusing the API and getting your account suspended
  • Performing other malicious actions that put your app and users at risk

Unfortunately, it‘s all too common for developers to accidentally expose their API keys. A study by North Carolina State University found that over 100,000 GitHub repositories contained exposed API keys, including keys for services like Amazon Web Services, Google Cloud, and Stripe (Meli et al., 2019).

Here are a few real-world examples of the consequences of exposed API keys:

  • In 2015, British Airways suffered a data breach that exposed over 400,000 customers‘ personal and payment information. The breach was caused by a third-party analytics script that contained a hard-coded API key (Whittaker, 2018).
  • In 2019, a security researcher found that the popular VideoLAN VLC media player‘s website was exposing a private Google API key. The key granted access to various Google services, including the ability to send email on behalf of VideoLAN‘s Gmail accounts (Cimpanu, 2019).
  • Also in 2019, an Indian government website exposed an API key for an SMS service, which allowed an attacker to send millions of unauthorized text messages (Sharma, 2019).

The lesson is clear: never include your API keys in client-side code or public repositories. But how do you use APIs in your frontend apps without exposing your keys? That‘s where serverless functions come in.

Securing API Keys with Serverless Functions

Serverless functions provide a way to execute backend code without managing your own servers. You can use serverless functions to handle your API requests and keep your keys secure on the backend, while still allowing your frontend code to access the data it needs.

Here‘s a simplified overview of how it works:

  1. Your frontend code makes a request to your serverless function‘s URL
  2. The serverless function securely authenticates with the third-party API using an API key stored in an environment variable
  3. The serverless function makes the request to the API and returns the response data to the frontend
  4. The frontend receives the data without ever being exposed to the API key

By moving the API request to the backend, you can keep your API keys hidden from the frontend and public repositories. Attackers won‘t be able to find your keys by inspecting your client-side code.

Netlify Functions

Netlify is a popular platform for deploying web applications and serverless functions. They offer a feature called Netlify Functions for writing and deploying serverless functions in JavaScript.

Netlify Functions are built on top of AWS Lambda, so you get the benefits of serverless computing without having to manage the infrastructure yourself. Netlify takes care of securely deploying and running your functions.

Here are some key features and benefits of Netlify Functions:

  • Easy to set up and deploy alongside your frontend code
  • Supports Node.js and JavaScript
  • Automatically handles routing and API gateway setup
  • Provides a generous free tier and pay-per-use pricing
  • Integrates with Netlify‘s continuous deployment and Git workflow

Tutorial: Using Netlify Functions to Hide API Keys

Now let‘s walk through a step-by-step tutorial on using Netlify Functions to securely fetch data from a third-party API in a frontend application.

Prerequisites

  • A Netlify account (sign up for free at netlify.com)
  • Node.js and npm installed on your machine
  • An API key for a service you want to use (we‘ll use the OpenWeather API in this example)

Step 1: Set up a new Netlify site

Create a new directory for your project and initialize a new npm project:

mkdir weather-app
cd weather-app
npm init -y

Create a new index.html file with a basic HTML structure:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Weather App</title>
</head>
<body>

  <div id="weather"></div>

  <script src="main.js"></script>
</body>
</html>

Create a main.js file and leave it empty for now.

Step 2: Set up a Netlify Function

Create a new directory called functions in your project root. This is where you‘ll put your serverless functions.

Inside the functions directory, create a new file called weather.js with the following code:

const axios = require(‘axios‘);

exports.handler = async (event, context) => {
  const { lat, lon } = event.queryStringParameters;
  const apiKey = process.env.WEATHER_API_KEY;

  const url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${apiKey}&units=metric`;

  try {
    const response = await axios.get(url);
    return {
      statusCode: 200,
      body: JSON.stringify(response.data)
    };
  } catch (error) {
    return {
      statusCode: 500,
      body: JSON.stringify({ error: error.message })
    };
  }
};

This function uses the axios library to make a request to the OpenWeather API. It expects latitude and longitude coordinates as query string parameters, and returns the weather data as JSON in the response body.

Notice that the API key is stored in an environment variable called WEATHER_API_KEY. We‘ll set this variable in the Netlify UI later. This way, the key is never exposed in your code.

Step 3: Install dependencies

In your project root, install the axios and netlify-lambda libraries:

npm install axios netlify-lambda

axios is used to make HTTP requests in the serverless function. netlify-lambda is a tool for building and serving lambda functions locally during development.

Step 4: Configure Netlify

Create a new file called netlify.toml in your project root with the following configuration:

[build]
  functions = "functions"

This tells Netlify where to find your serverless functions.

Step 5: Create a Netlify site

Log in to Netlify and click "New site from Git". Choose your Git provider and repository.

In the deploy settings, set the publish directory to dist and the build command to npm run build.

Click "Show advanced" and add an environment variable called WEATHER_API_KEY with your OpenWeather API key as the value.

Click "Deploy site".

Step 6: Call the function from your frontend code

In your main.js file, add the following code:

const getWeather = async (lat, lon) => {
  const url = `/.netlify/functions/weather?lat=${lat}&lon=${lon}`;
  const response = await fetch(url);
  const data = await response.json();
  return data;
};

const displayWeather = (weather) => {
  const weatherDiv = document.getElementById(‘weather‘);
  weatherDiv.innerHTML = `
    <p>Temperature: ${weather.main.temp}°C</p>
    <p>Description: ${weather.weather[0].description}</p>
  `;
};

const main = async () => {
  const weather = await getWeather(51.5074, -0.1278); // London coordinates
  displayWeather(weather);
};

main();

This code calls the weather function with hardcoded coordinates for London, and displays the temperature and weather description on the page.

Step 7: Test locally

To test your function locally, run the following command in your terminal:

netlify dev

This will start a local development server. Visit http://localhost:8888 to see your app.

Step 8: Deploy to production

When you‘re ready to deploy your app to production, push your code to your Git repository. Netlify will automatically detect the changes and deploy your site.

Your serverless function will be available at https://your-site.netlify.com/.netlify/functions/weather.

Best Practices for API Key Security

Securing your API keys is an ongoing process, not a one-time task. Here are some best practices to keep in mind:

  • Never expose API keys in client-side code or public repositories
  • Use environment variables to store and manage your keys
  • Rotate your keys regularly, especially if you suspect they may have been compromised
  • Monitor your API usage and set up alerts for unexpected spikes or suspicious activity
  • Use secure authentication methods like OAuth 2.0 or JSON Web Tokens (JWT) when possible
  • Follow the principle of least privilege: only give your keys the permissions they need
  • Educate your team on API key security best practices and make sure everyone follows them

Alternatives to Netlify Functions

While Netlify Functions are a great option for securing API keys, there are other serverless function providers and approaches to consider:

  • AWS Lambda: You can use AWS Lambda directly to write and deploy serverless functions in various languages. AWS offers more flexibility and customization than Netlify Functions, but requires more setup and management.
  • Vercel Serverless Functions: Vercel (formerly ZEIT) offers serverless functions similar to Netlify, with support for Node.js, Go, Python, and more.
  • Google Cloud Functions and Azure Functions: Google and Microsoft also offer serverless function platforms with various language and integration options.
  • Self-hosted solutions: You can set up your own backend server or API proxy to handle API requests and keep your keys secure. This gives you full control over your infrastructure, but requires more maintenance and expertise.

The right approach depends on your specific needs, budget, and expertise. Netlify Functions are a great choice for developers looking for an easy and integrated solution, especially if you‘re already using Netlify for deployment.

Conclusion: Securing Your Keys is Essential

As a full-stack developer, it‘s your responsibility to protect your users‘ data and keep your application secure. Hiding your API keys and other sensitive credentials is a critical part of that responsibility.

Serverless functions provide a convenient and scalable way to secure your API keys by moving sensitive code to the backend. Netlify Functions make it easy to deploy serverless functions alongside your frontend code, with minimal setup and management.

By following best practices and using the right tools and techniques, you can keep your API keys safe and focus on building great applications.

Additional Resources

References

Similar Posts