When we develop web applications with Astro, we frequently need to interact with external APIs and services. Managing credentials and API keys securely is crucial to protecting our applications. In this guide, we will explore best practices for managing API keys and environment variables in Astro projects.
In Astro, environment variables are handled similarly to other modern frameworks. First, we create a .env file in the root of our project:
# .env PUBLIC_API_URL=https://api.ejemplo.com PRIVATE_API_KEY=tu_clave_secreta DATABASE_URL=postgresql://usuario:password@localhost:5432/db
For TypeScript, it is advisable to create an env.d.ts file to type our variables:
/// <reference types="astro/client" /> interface ImportMetaEnv { readonly DATABASE_URL: string; readonly PRIVATE_API_KEY: string; readonly PUBLIC_API_URL: string; } interface ImportMeta { readonly env: ImportMetaEnv; }
In Astro, we can access environment variables in different ways depending on the context:
--- // En archivos .astro const apiKey = import.meta.env.PRIVATE_API_KEY; const publicUrl = import.meta.env.PUBLIC_API_URL; ---
// En archivos .ts o .js const apiKey = import.meta.env.PRIVATE_API_KEY;
Astro follows an important convention for environment variables:
# .env PUBLIC_API_URL=https://api.publica.com # ✅ Visible en el cliente PRIVATE_API_KEY=secreto123 # ⛔ Solo servidor
To handle APIs that require authentication, we must create serverless endpoints:
// src/pages/api/data.ts export async function GET() { try { const response = await fetch('https://api.externa.com/data', { headers: { 'Authorization': `Bearer ${import.meta.env.PRIVATE_API_KEY}` } }); const data = await response.json(); return new Response(JSON.stringify(data), { status: 200, headers: { 'Content-Type': 'application/json' } }); } catch (error) { return new Response(JSON.stringify({ error: 'Error al obtener datos' }), { status: 500 }); } }
Implement a validation function at the start of your application:
// src/utils/validateEnv.ts export function validateEnv() { const requiredEnvVars = [ 'DATABASE_URL', 'PRIVATE_API_KEY', 'PUBLIC_API_URL' ]; for (const envVar of requiredEnvVars) { if (!import.meta.env[envVar]) { throw new Error(`La variable de entorno ${envVar} es requerida`); } } } // src/pages/index.astro --- import { validateEnv } from '../utils/validateEnv'; if (import.meta.env.MODE === 'development') { validateEnv(); } ---
Create different files for each environment:
.env # Variables por defecto .env.development # Variables de desarrollo .env.production # Variables de producción .env.local # Variables locales (ignoradas en git)
Provides a .env.example file:
# .env.example PUBLIC_API_URL=https://api.ejemplo.com PRIVATE_API_KEY=tu_clave_aqui DATABASE_URL=postgresql://usuario:password@localhost:5432/db
Make sure to include sensitive files in .gitignore:
# .env PUBLIC_API_URL=https://api.ejemplo.com PRIVATE_API_KEY=tu_clave_secreta DATABASE_URL=postgresql://usuario:password@localhost:5432/db
/// <reference types="astro/client" /> interface ImportMetaEnv { readonly DATABASE_URL: string; readonly PRIVATE_API_KEY: string; readonly PUBLIC_API_URL: string; } interface ImportMeta { readonly env: ImportMetaEnv; }
--- // En archivos .astro const apiKey = import.meta.env.PRIVATE_API_KEY; const publicUrl = import.meta.env.PUBLIC_API_URL; ---
// En archivos .ts o .js const apiKey = import.meta.env.PRIVATE_API_KEY;
# .env PUBLIC_API_URL=https://api.publica.com # ✅ Visible en el cliente PRIVATE_API_KEY=secreto123 # ⛔ Solo servidor
// src/pages/api/data.ts export async function GET() { try { const response = await fetch('https://api.externa.com/data', { headers: { 'Authorization': `Bearer ${import.meta.env.PRIVATE_API_KEY}` } }); const data = await response.json(); return new Response(JSON.stringify(data), { status: 200, headers: { 'Content-Type': 'application/json' } }); } catch (error) { return new Response(JSON.stringify({ error: 'Error al obtener datos' }), { status: 500 }); } }
// src/utils/validateEnv.ts export function validateEnv() { const requiredEnvVars = [ 'DATABASE_URL', 'PRIVATE_API_KEY', 'PUBLIC_API_URL' ]; for (const envVar of requiredEnvVars) { if (!import.meta.env[envVar]) { throw new Error(`La variable de entorno ${envVar} es requerida`); } } } // src/pages/index.astro --- import { validateEnv } from '../utils/validateEnv'; if (import.meta.env.MODE === 'development') { validateEnv(); } ---
Secure handling of API keys and environment variables is crucial for any modern web application. By following these best practices at Astro, we can:
The above is the detailed content of API Keys and Environment Variables in Astro: Complete Security Guide. For more information, please follow other related articles on the PHP Chinese website!