Original article: How to Hide API Keys in Frontend Apps using Netlify Functions

Netlify es una plataforma muy popular para desarrollo web que facilita la compilación, despliegue y administración de sitios web.

Puedes usar Netlify como hosting para tus sitios y te ayuda a editarlos y publicar los cambios que realices. También te brinda características adicionales como seguridad, servicios de autenticación y autorización de usuarios y más.

Esta guía se enfoca en mostrarte como configurar una función serverless en Netlify para ocultar las API keys de la aplicación del lado del cliente.

Para esta lección crearás un motor de búsqueda de imágenes y lo desplegarás en Netlify, que además realizará llamadas a la API de Pixabay usando funciones serverless.

Este es el mismo proceso para cualquier otra aplicación front-end (cliente) elaborada con JavaScript, con librerías JavaScript o frameworks JS como ReactJS, NextJS, VueJS, Angular, etc.

Prerrequisitos

Para seguir los pasos en este tutorial deberás contar con lo siguiente:

  • Una cuenta en Netlify (regístrate aquí)
  • Entendimiento básico de APIs RESTFUL, funciones Lambda y conceptos de asincronía (async/await).

El demo terminado lo puedes encontrar en la rama principal de GitHub o en este enlace: https://netlify-func-demo.netlify.app.

¿Qué es una función Netlify?

Una función Netlify es una función serverless o lambda cuyo acceso es provisto por Netlify. Se usan para desplegar código serverless o lógica de "servidor" (back-end) pero sin la necesidad de realmente administrar un servidor dedicado.

El propósito de una función Netlify es manejar código con base en eventos (event-driven) y enviar solicitudes HTTP que devuelvan una respuesta en formato JSON.

"Las funciones serverless, llamadas comercialmente "funciones Netlify" por ejecutarse en la plataforma de Netlify, son una manera de desplegar código del lado del servidor en forma de API endpoints" - Documentación Netlify

La función accede de manera segura el entorno de las variables en segundo plano ("tras bamablinas") mediante una función lambda de Amazon Web Services (AWS).

Las credenciales secretas como los tokens de acceso o claves API que se ocultan sólo usando variables de entorno son menos seguras. Esto se debe a que pueden ser fácilmente obtenidas usando las "Developer Tools" (herramientas de desarrollo) a traves de la API "fetch request" del navegador.

Las claves API, si son interceptadas pueden ser mal usadas por actores maliciosos lo que podría afectar a tu aplicación o incrementar tus costos si esta depende de un servicio API de paga.

Otras funciones serverless utilizadas para ejecutar código sin tener que manejar servidores incluyen: las AWS Lambda Functions, Azure Functions y Google Cloud Functions.

Cómo configurar una aplicación cliente

Cómo clonar la aplicación demo

Para empezar con este tutorial puedes clonar la "aplicación motor de búsqueda de fotos de stock" desde su  repositorio GitHub. Mira la previsualización en Netlify en https://netlify-func-demo.netlify.app.

El primer paso es clonar el repositorio:

git clone https://github.com/frankiefab100/netlify-serverless-functions-demo.git

Paso siguiente, cambia (ingresa) al directorio netlify-serverless-functions-demo.

 cd netlify-serverless-functions-demo

Luego tendrás que instalar las dependencias.

npm install
#OR 
yarn add

Ahora ejecuta el servidor de desarrollo. Ejecuta el siguiente comando para este propósito:

netlify dev

La aplicación estará disponible en: https://localhost:8888.

Alternativamente puedes omitir los pasos anteriores si quieres crear la aplicación desde cero. En el próximo paso crearás una aplicación JavaScript para la búsqueda de fotos stock.

Cómo construir la aplicación demo usando JavaScript

El primer paso es configurar la aplicación front-end (cliente). Abre tu editor de código favorito como, por ejemplo: VS Code.

A continuación, crea la carpeta dist y dentro crea el archivo index.html. Copia y pega ahí el siguiente código:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="style.css" />
    <title>Stock Photos Search Engine</title>
  </head>
  <body>
    <div class="container">
      <header>
        <h1>Search For Stock Photos</h1>
        <div class="search-section">
          <input
            type="text"
            name="search"
            class="search"
            placeholder="Enter a keyword"
          />
          <input
            id="searchBtn"
            class="search-btn"
            type="submit"
            value="Search"
          />
        </div>
      </header>

      <div class="photo-wrapper">
        <img src="" alt="" class="photo" />
      </div>
    </div>

    <script src="./script.js" type="module"></script>
  </body>
</html>

En el mismo directorio dist agrega la siguiente hoja de estilos en un archivo llamado style.css:

/* dist/style.css */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  color: #222;
  font-family: "Roboto", sans-serif;
  font-size: 1rem;
  margin: 0 auto;
  width: 100vw;
  height: 100vh;
}

.container {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  min-height: 100vh;
  min-width: 100vw;
  width: 100%;
  height: 100%;
}

h1 {
  padding-bottom: 20px;
}

.search-section {
  display: inline;
  text-align: center;
  min-width: 310px;
}

.search,
.search-btn {
  border: none;
  border-radius: 5px;
  font-size: 1rem;
  padding: 15px;
  height: 50px;
}

.search {
  background-color: #d1f3bf;
  color: #222;
  min-width: 225px;
}

.search-btn {
  background-color: #04ab04;
  color: #f6f6f6;
  cursor: pointer;
  margin-left: 5px;
  min-width: 80px;
  transition: all 0.3s ease-in-out;
}

.search-btn:hover {
  background-color: #2dc22d;
}

.photo-wrapper {
  display: flex;
  gap: 15px;
  margin: 30px;
}

.photo-wrapper img {
  width: 200px;
}

Crea una cuenta gratuita en Pixabay

El primer paso para utilizar la Pixabay API es darse de alta una cuenta con tu correo electrónico.

Pixabay-API-Documentation
Pixabay API key section

Como se muestra en la imagen de arriba, tus llaves API las puedes encontrar debajo de la seccion de parámetros en la página oficial de documentación de Pixabay API.

Crea una variable de entorno

Las variables de entorno (comúnmente abreviadas como "env") son combinaciones pares de clave/valor que pueden afectar el comportamiento y los procesos de un sistema operativo o aplicación.

Usar variables de entorno se recomienda para configurar servicios de terceros y sus credenciales durante el desarrollo.

Instala dotenv

Una vez que haya completado la creación de tu cuenta en Pixabay, abre tu terminal e instala el paquete dotenv. Esto permitirá que tu aplicación pueda leer las variables de entorno del archivo .env.

npm install dotenv
#O bien
yarn add -D dotenv
Usando tu terminal o línea de comandos

En el próximo paso podrás guardar la clave API en el archivo .env.

Crea el archivo .env

En la raíz del directorio de tu aplicación crea el archivo .env y almacena las llaves (keys) API copiadas de tu perfil Pixabay.

PIXABAY_API_KEY=123456-7890

Donde PIXABAY_API_KEY=123456-7890 representa la llave y su valor asociado.

Nota: Reemplaza este par clave/valor con el valor apropiado.

Crea el archivo .gitignore

Para evitar incluir archivos y valores sensibles como node_modules y secret keys  en cada commit en repositorios públicos, crea el archivo .gitignore en la misma carpeta raíz del proyecto y agrega lo siguiente:

node_modules
.env
.netlify
.gitignore

La carpeta .netlify que contiene funciones serverless compiladas y otros archivos serán excluidos cuando el proyecto se empuje a GitHub o a cualquier otro sistema de control de versiones.

Crea una función get request

Ahora deberás añadir la lógica para realizar la petición fetch en el archivo script.js. Ajustaremos la lógica más adelante usando funciones Netlify.

/* dist/script.js */
const dotenv = require("dotenv").config();

const searchbar = document.querySelector(".search");
const submitBtn = document.querySelector(".search-btn");
const photoWrapper = document.querySelector(".photo-wrapper");

submitBtn.addEventListener("click", () => {
  getPhoto(searchbar.value);
  searchbar.value = "";
});

window.addEventListener("keydown", (e) => {
  if (e.keyCode === 13) {
    getPhoto(searchbar.value);
    searchbar.value = "";
  }
});

async function getPhoto(keyword) {
  const apiKey = PIXABAY_API_KEY;
  let apiURL = `https://pixabay.com/api/?key=${apiKey}&q=${keyword}&image_type=photo&safesearch=true&per_page=3`;

  try {
    const response = await fetch(apiURL, {
      method: "GET",
      headers: { accept: "application/json" },
    });
    const data = await response.json();

    let imageURL = data.hits;

    imageURL.forEach((result) => {
      let imageElement = document.createElement("img");
      imageElement.setAttribute("src", `${result.webformatURL}`);
      photoWrapper.appendChild(imageElement);
    });
  } catch (error) {
    alert(error);
  }
}

Nota: Como he mencionado anteriormente, si se publica este repositorio en GitHub, podremos acceder a la clave API en el "lado del cliente" desde un navegador, aunque hayamos excluido el archivo .env, mas adelante veremos como.

Para ilustrar esto, selecciona la rama testing del repositorio de esta aplicación. La previsualización del sitio mostrara los siguientes errores de referencia (Reference Errors) en la consola del navegador:

Uncaught ReferenceError: require is not defined
Uncaught ReferenceError: require is not defined at getPhotos
Uncaught ReferenceError: process is not defined at getPhotos

Esto se debe a que no hay manera de vincular con las variables de entorno especificadas en el archivo .env, ya que este no se envió en el commit al repositorio público en GitHub.

En el siguiente paso, selecciona y clona la rama testing en tu máquina de forma local con los siguientes comandos:

git clone https://github.com/frankiefab100/netlify-serverless-functions-demo.git
cd netlify-serveless-functions-demo
npm install
netlify dev

La aplicación estará disponible en tu navegador en la dirección localhost:8888.

Ahora abre las herramientas para desarrolladores (Developer Tools) o haz clic derecho y selecciona inspeccionar. O puedes presionar la tecla F12. Luego vea la pestaña Network y haz clic en la URL de la petición del archivo getPhotos.js.

Screenshot--124----Copy
Clave API mostrada en la pestaña Red (Network) en las herramientas de Desarrollo

Ahora deberías poder ver la clave API expuesta públicamente en la sección de encabezados de la pestaña Network donde fue devuelta con los datos de la respuesta en tu navegador.

Esto es un problema de seguridad ya que la pestaña Network en las herramientas de desarrollo típicamente permite mostrar información tal como la URL de la petición, el estado y los datos de la respuesta.

Screenshot--127----Copy
Clave de la API devuelta como dato de respuesta y expuesto en el URL de la petición

En la siguiente sección encontraras la manera segura de ocultas la clave API utilizando las funciones Netlify.

Cómo empezar a usar Netlify Functions

Primero, necesitarás iniciar sesión en tu terminal e instalar la Netlify CLI y Lambda como dependencias de desarrollo. Puedes hacerlo al ejecutar este comando:

npm install -g netlify-cli netlify-lambda
#OR 
yarn add -D netlify-cli netlify-lambda --save-dev

Agrega los comandos personalizados build y dev en package.json

Estos comandos, crearán e iniciarán la aplicación en el servidor y también la ejecutarán en el nevegador.  Aquí puedes ver un ejemplo de como podrías agregar este script con comandos en el archivo package.json:

"scripts": {
   "build": "npm run-script",
   "dev": "netlify dev"
 }

Instala Axios

Usaremos el método axios.get porque esta función de Node difiere del método fetch en que este último está pensado para correr en el navegador.

Para instalar Axios, abre tu terminal e ingresa el comando:

npm install axios
#OR
yarn add -D axios

En este caso vamos a trabajar nuestra aplicación solo con JavaScript puro (vanilla JS), es decir sin usar librerías o marcos de trabajo para nuestro frontend, por lo que deberás importar axios de la siguiente manera:

const axios = require("axios");

Para cuando se usan librerias como React, debes importar asi:

import axios from "axios";

Crea una función serverless

En la raíz del proyecto, crea una carpeta llamada netlify y a su vez dentro de este crea otra carpeta functions. En esta carpeta functions crea un archivo llamado getPhotos.js.

Crearás una función serverless en el archivo getPhotos. Esto ocultará efectivamente las llaves API cuando traigamos las imágenes desde la API de Pixabay.

//netlify/functions/getPhotos.js 
require("dotenv").config();

const axios = require("axios");

exports.handler = async (event, context) => {
  try {
    const { keyword } = event.queryStringParameters;
    let response = await axios.get(
      `https://pixabay.com/api/?key=${process.env.PIXABAY_API_KEY}&q=${keyword}&image_type=photo&safesearch=true&per_page=3`,
      {
        headers: { Accept: "application/json", "Accept-Encoding": "identity" },
        params: { trophies: true },
      }
    );

    let imageURL = response.data.hits;

    return {
      statusCode: 200,
      body: JSON.stringify({ imageURL }),
    };
  } catch (error) {
    return {
      statusCode: 500,
      body: JSON.stringify({ error }),
    };
  }
};

Aquí la clave process.env.PIXABAY_API_KEY hace referencia al entorno de configuración de la clave API especificado en el archivo .env para el modo de desarrollo.

El parámetro keyword acepta una cadena de texto (string) que es accesible en la propiedad queryStringParameters y devuelve datos commo respuesta almacenados en la variable imageURL. Esta será enviada al archivo script.js como respuesta a la petición (veremos esto más adelante).

Si la petición GET es exitosa, devolverá una respuesta con el código (statusCode) 200 y el objeto JSON correspondiente. En caso de errores, recibiremos una alerta con el mensaje y código de estado.

Debido a cambios de versión, Axios podría devolver un Buffer como respuesta en tu terminal que se vera algo como esto:

netlify-data
Buffer de respuesta de Axios en la terminal

Para evitar esto deberás adjuntar lo siguiente a la petición GET:

 let response = await axios.get(
      `https://pixabay.com/api/?key=${process.env.PIXABAY_API_KEY}&q=${keyword}&image_type=photo&safesearch=true&per_page=3`,
      {
        headers: { Accept: "application/json", "Accept-Encoding": "identity" },
        params: { trophies: true },
      }
    );

Crea un archivo de configuracion Netlify

En la raíz del proyecto, crea el archivo netlify.toml. Este archivo especifica como es que Netlify construirá y desplegará tu aplicación.

Ahora, agrega la siguiente configuración en el archivo netlify.toml:

[build]
  command = "npm run build"
  functions = "netlify/functions"
  publish = "dist"

Nota:

  • command = "npm run build" ejecuta la Netlify CLI (Interfaz de Línea de Comandos) para que realice la construcción de la aplicación a partir de las funciones.  
  • functions = "netlify/functions" indica que las funciones en getPhotos existen en ña carpeta netlify/functions.
  • publish = "dist" identifica dist como la carpeta desde donde será "servido" este archivo.

Edita el archivo script.js con la URL para las peticiones a Netlify functions

Siguiente paso, edita la apiURL de esto:

let apiURL = `https://pixabay.com/api/?key=${apiKey}&q=${keyword}&image_type=photo&safesearch=true&per_page=3`;

A esto (el endpoint para la petición HTTP a las Netlify Functions):

  let apiURL = `/.netlify/functions/getPhotos?keyword=${keyword}`;

Esta función "serverless" será consultada desde el lado del cliente de tu aplicación mediante el endpoint: /.netlify/functions/getPhotos. Una vez que la solicitud es enviada, la función getPhotos será invocada desde script.js.

La respuesta imageURL obtenida de la Netlify functions getPhotos será pasada o enviada como el valor asignado al parámetro keyword en el "query string" (cadena de texto de consulta) de la función. Su contenido será recorrido mediante un ciclo for para devolver las 3 imágenes desde la API de Pixabay.

El archivo script.js debe verse así:

/* dist/script.js */
const searchbar = document.querySelector(".search");
const submitBtn = document.querySelector(".search-btn");
const photoWrapper = document.querySelector(".photo-wrapper");

submitBtn.addEventListener("click", () => {
  getPhoto(searchbar.value);
  searchbar.value = "";
  photoWrapper.innerHTML = "";
});

window.addEventListener("keydown", (e) => {
  if (e.keyCode === 13) {
    getPhoto(searchbar.value);
    searchbar.value = "";
    photoWrapper.innerHTML = "";
  }
});

async function getPhoto(keyword) {
  let apiURL = `/.netlify/functions/getPhotos?keyword=${keyword}`;

  try {
    const response = await fetch(apiURL, {
      method: "GET",
      headers: { accept: "application/json" },
    });
    const data = await response.json();

    for (let i = 0; i < data.imageURL.length; i++) {
      let imageElement = document.createElement("img");
      imageElement.setAttribute("src", `${data.imageURL[i].webformatURL}`);
      photoWrapper.appendChild(imageElement);
    }
  } catch (error) {
    alert(error);
  }
}

Nota: En el código de arriba mantiene tu variable de entorno segura ya que se accede a esta desde una función serverless.

Ejecuta el servidor de desarrollo

Ahora, ejecuta tu aplicación con el siguiente comando:

netlify dev

Esto hará que se cargue la función getPhotos mediante https://localhost:8888/.netlify/functions/getPhotos.

netlify-dev-terminal
Resultado en terminal de netlify build

Luego, inicia el servidor de desarrollo y lanza la aplicación en tu navegador por defecto en  localhost:8888.

netlify-success2
La función Netlify está ahora lista en https://localhost:8888

En este punto, la configuración de la función Netlify está completa y ya es posible realizar solicitudes GET HTTP.

Cómo realizar solicitudes para traer datos

Ahora que ya tienes la aplicación servida, hagamos una solicitud (fetch) para traer datos. Ingresa algún texto en el campo input y dale Enter o haz clic en el botón para traer las imágenes desde la API de Pixabay.

Stock-Photos-Search-Engine--1-
Imágenes de flores buscados dese la API de Pixabay

Para mayor información acerca del API de Pixabay, ve a su sitio oficial de documentación.

El comando anterior enviará una solicitud a la función serverless y luego devolverá seis respuestas. Aquí cómo se verá la respuesta en la ventana de tu terminal:

Request from ::1: GET /.netlify/functions/getPhotos?keyword=flower
Response with status 200 in 4895 ms.

También puedes utilizar las herramientas de desarrollador (Developer Tools) en la pestaña Network (Red) para validar la solicitud.

Screenshot--118----Copy
Datos de respuesta de la función serverless de la API

La solicitud devuelve la URL de nuestra aplicación, la función Netlify getPhotos, el script.js y las imágenes de Pixabay.

Screenshot--120-
Respuesta de la petición realizada a la función Netlify vista en la sección de encabezado en la pestaña de Red (Network) del navegador.

Cómo hospedar la aplicación en el repositorio remoto

Ahora, deberías empujar tu proyecto al hosting de control de versiones GitHub.

git add .
git commit -m"initial commit"
git push origin -u main

Cómo desplegar la aplicación y la función serverless en Netlify

Una vez que hayas publicado el proyecto en GitHub, inicia sesión en Netlify y conecta tu cuenta GitHub para dar autorización.

Screenshot--130-
Importar un proyecto para despliegue en Netlify

Como se muestra en la imagen de arriba, haz clic en Add New Projecty luego busca el repositorio de tu aplicación en la lista desplegable. Enseguida, haz clic en Build Your Site. Esto tomará algunos minutos en completarse.

Acabas de desplegar la aplicación usando la UI de Netlify. Ahora tu aplicación estará disponible en: https://netlify-func-demo.netlify.app.

La URL para peticiones "fetch" (del inglés traer) debería verse como ésta: https://netlify-func-demo.netlify.app/.netlify/functions/getPhotos.

Opcional - Cómo configurar la aplicación desde el tablero Netlify

Alternativamente, puedes configurar el comando Netlify desde el tablero (o panel de control, del inglés, Dashboard). Si estas configuraciones ya han sido especificadas en el archivo netlify.toml, se sobreescribirán cualquier configiracion correspondiente.

Primero, selecciona la configuración de la carpeta del proyecto en "Site settings".

Site-overview-netlify-func-demo1
Opciones de Sitio para la carpeta del proyecto en Netlify

Configura el comando Build y el directorio público

Ve a Site settings> Deploy > Build & Deploy, edita los siguientes comandos y luego guarda los cambios:

  • Commando build: npm run build
  • Directorio público: dist
Screenshot--132-
Sección de Construcción y despliegue en Netlify

Configura la carpeta de las funciones

Por defecto, Netlify utiliza netlify/functions como el directorio en el cual encontrar las funciones a desplegar. En este caso, nuestra función serverless getPhotos se encuentra en la carpeta netlify/funcions.

Ahora configuraremos una carpeta personalizada donde Netlify puede encontrar tus funciones compiladas. Ve a Site settings > Functions e ingresa la ruta la carpeta en donde se encuentran almacenadas las funciones de tu repositorio.

Screenshot--131-
Sección de Carpeta de Funciones en Netlify

Cómo configurar variables de entorno para producción

En el panel de control de Netlify (Dashboard) haz clic en Site settings > Build & deploy > Environment> Environment varibales y luego configura el par clave/valor de la siguiente manera:

PIXABAY_API_KEY=your-api-key-here
Screenshot--133-
Sección de Variables de Entorno en Netlify

Haz clic en guardar, y enseguida redespliega la aplicación para que los cambios se apliquen.

Para redesplegar la aplicación en Netlify, ve a Deploys > Trigger deploy. A continuación, selecciona Clear cache and redeploy site.

Screenshot--134-
Ejecuta el redespliegue en la pestaña "Deploys" en Netlify

Nota: El nombre de la variable de entorno (PIXABAY_API_KEY) debe coincidir con el que se referencia en el código en getPhotos.

Para una aplicación React, usa el prefijo REACT_APP_ para que puedan ser leídas desde el archivo .env.

 REACT_APP_PIXABAY_API_KEY=your-api-key-here

Cómo inicializar la función serverless desde la aplicación remota

Para conectar la carpeta de tu proyecto a la aplicación web ya desplegada, inicia sesión en tu cuenta Netlify desde la terminal:

netlify login

A continuación, inicializa la aplicación en Netlify ejecutando el siguiente comando en tu terminal:

netlify init

Tu aplicación ahora está configurada para despliegues continuos via Netlify.

Cómo compilar la función serverless de Netlify

Necesitas enlazar tu aplicación con el ID del sitio en Netlify antes de poder ejecutar el comando build en tu terminal. Para conectar la carpeta local de tu proyecto con el ID de tu sitio en Netlify, ingresa el siguiente comando en tu terminal:

netlify link

Luego de esto, se te pedirá que enlaces la carpeta mediante cualquiera de las siguientes formas:

  • Búsqueda por nombre completo o parcial del sitio.
  • Elegir de una lista de tus sitios recientemente editados.
  • Ingresa el ID de tu sitio.

Una vez que hayas seleccionado tu opción preferida, se habrá enlazado la carpeta de tu proyecto con el sitio hospedado en Netlify. Esto te permite ejecutar comandos con la CLI de Netlify y automáticamente desplegar el proyecto desde el repositorio cada que haya cambios en el código.

En el siguiente paso, compilarás una función serverless mientras se ejecuta en el servidor. Para correr el comando build definido en el archivo netlify.toml, ejecuta el siguiente comando:

netlify build

Esto a su vez, ejecutará el comando npm run-script como fue especificado en el package.json. Ahora, tu función serverless que está en la carpeta netlify/functions será empaquetado ¡exitosamente!

Cómo poner a prueba la aplicación

Para realizar pruebas y confirmar que la función Netlify funciona correctamente, ejecuta el comando siguiente en tu terminal:

netlify functions:serve

Esto inyecta las variables de entorno de tu proyecto del archivo .env y ejecuta la función serverless..

Cómo confirmar la seguridad de la clave API Keys

Para inspeccionar tu aplicación y confirmar que las claves API se encuentran ocultas sigue los pasos a continuación:

Haz clic en la URL de tu aplicación hospedada y una vez abierta, navega a las herramientas de desarrollador (Developer Tools) presionando la tecla F12 o haciendo clic en cualquier lugar y seleccionando Inspeccionar. Navega a la pestaña de Red, donde deberías ver los datos traídos desde la API Pixabay.

Screenshot--128-
Clave API ahora oculta de la vista pública usando las herramientas de desarrollador (Developer Tools). 

Ahora ya has confirmado que has configurado exitosamente una función serverless y la has desplegado en Netlify.

Conclusión

Este tutorial introdujo las funciones serverless, JavaScript asíncrono y conceptos de APIs RESTful.

Espero que ahora sepas cómo crear funciones serverless/lambda y mantener de manera segura cualquier valor sensible como las llaves/claves API que utiliza tu aplicación del lado del cliente.

Si te atoraste con algo, puedes tener acceso al código completo en el Repositorio en GitHub.

¡Gracias por leer el artículo! Sígueme en Twitter.

Enlaces relevantes