Pregunta 1Cuando envías una solicitud con una clave de API añadida, ¿qué puede determinar el servicio externo?
Claves de API y servicios externos — qué protege una clave y los webhooks
Este artículo forma parte del curso Fundamentos de informática, que construye desde cero los conocimientos prácticos de informática que necesitas como mínimo para programar y hacer vibe coding.
Una clave de API es una cadena que indica de quién es esa llamada. Con diagramas comprobamos dónde puedes guardarla y en qué dirección va un webhook, la solicitud que el servicio externo envía a tu servidor.
Este artículo trata dos cosas: la clave de API que usas al llamar a un servicio externo y el webhook que el servicio externo llama desde su lado.
Verás dónde se emite una clave, qué indica esa cadena y dónde ponerla para que nadie más pueda leerla.
- Dónde emites una clave de API y en qué parte de la llamada la añades
- Que una clave es una cadena que indica de quién es la llamada y su relación con el cobro por uso
- Dónde se puede guardar una clave y qué pasa si la escribes en un sitio que llega al navegador
- El webhook que se llama desde el lado del servicio externo y la comprobación de la firma
La clave de API se emite en el panel de control del servicio que usas
Para llamar a un servicio externo, primero recibes del proveedor una clave de API (API key: una cadena que le indica al proveedor de qué usuario es la llamada).
No es un valor que decidas tú: lo emite y te lo entrega el servicio que usas.
Ya sean pagos, mapas o generación de texto, la secuencia registrarte, emitir una clave y ponerla en tu propio servidor no cambia.
Copia la cadena emitida en ese mismo momento y ponla en el archivo .env de tu propio servidor.
Muchos servicios externos funcionan con cobro por uso (pagas solo por lo que usas) y facturan según el número de llamadas y el volumen de datos enviados y recibidos.
Si una clave sale fuera, las llamadas que hagan otros también entran en la factura del dueño.
La clave de API es una cadena que indica de qué usuario es la llamada
La API de un servicio de pagos es una URL pública, así que necesita una forma de saber de quién es la llamada que le llega.
El sitio donde se añade no es la URL, sino la cabecera de la solicitud (request header: la parte que, aparte del cuerpo, enumera en pares de nombre y valor cosas como el remitente y el formato).
- POST https://api.pay.example.com/v1/charges
- Solo dice adónde va y a qué
- La clave de API se escribe aquí
- Authorization: Bearer sk_live_a1b2
- Un par de nombre y valor por línea
- Los datos que envías, en JSON
- Suele ir vacío en llamadas que solo consultan
La segunda línea del marco central es la línea donde va la clave.
Authorization es el nombre de la cabecera, Bearer es la palabra que indica cómo se pasa el valor, y lo que sigue es el valor de la clave.
Tanto ese nombre como esa forma de escribirlo los decide el proveedor.
Con la clave que le llega, el servicio de pagos determina tres cosas: el dueño, las operaciones permitidas y el número de llamadas.
| Lo que hizo my-app | Cabecera Authorization | Lo que hace el servicio de pagos | Lo que devuelve |
|---|---|---|---|
| Obtener la lista de pagos | Bearer sk_live_a1b2 | Determina el dueño y comprueba el alcance | 200 y JSON |
| Obtener la lista de pagos | Se olvidó de añadirla | No puede determinar el dueño | Devuelve 401 |
| Crear un pago | Bearer sk_read_9f3c | Solo permite leer | Devuelve 403 |
| Llamar muchas veces en poco tiempo | Bearer sk_live_a1b2 | Cuenta las llamadas de cada dueño | Devuelve 429 |
Con un 401, comprueba el valor de la clave y el nombre de la cabecera; con un 403, qué operaciones están permitidas.
El límite de la cuarta fila es el límite de tasa (rate limit: el número máximo de llamadas que se aceptan en un periodo dado), y superarlo devuelve 429.
La clave indica de quién es la llamada
La clave de API es una cadena cuyo único trabajo es decir de quién es esta llamada.
El servicio de pagos mira la clave para comprobar el dueño y las operaciones permitidas y cuenta las llamadas de esa persona, así que sin clave devuelve 401, con una operación no permitida 403 y con demasiadas llamadas 429.
No pongas la clave en código que llega al navegador: guárdala solo dentro de tu propio servidor
Cualquiera que tenga la clave puede llamar como si fuera su dueño.
No hay ninguna pantalla que compruebe si es la persona real.
- PAY_API_KEY=sk_live_a1b2
- Se guarda en un archivo aparte del código
- Añade a la llamada la clave leída de .env
- El archivo en sí no se envía al dispositivo
- index.html y script.js
- No llama directamente al servicio de pagos: se lo pide a tu propio servidor
- Solo guarda claves emitidas para usarse desde el navegador
Aun siendo la misma clave, dónde la escribes cambia quién puede leerla.
| Dónde está escrita la clave | ¿Llega al dispositivo? | Quién puede leerla | Qué pasa |
|---|---|---|---|
| .env (dentro del servidor) | No llega | Solo quien accede al servidor | Funciona según lo contratado |
| script.js | Llega | Todos los que abren la página | Otros pueden llamar como tú |
| Un server.js publicado | No llega, pero queda público | Todos los que ven el código | No se puede borrar del historial de Git |
Cuantas más personas pueden leer la clave en una fila, más cerca está esa fila de que otros llamen en tu nombre.
La tercera fila no llega al navegador, pero una vez registrada en Git se puede leer en el historial de cambios aunque la borres después.
Cuando las instrucciones dicen «ponla en .env», te están diciendo que uses la colocación de la primera fila.
Con una clave que ha salido fuera se pueden hacer dos cosas, y no tienen el mismo efecto.
El valor que alguien leyó sigue siendo válido, y además queda en el historial de cambios de Git.
La de la derecha es la revocación (revoke: dejar en el proveedor una clave ya emitida en estado inservible).
Guarda la clave solo donde no llegue a ningún dispositivo
Cualquiera que tenga la clave puede usarla como su dueño.
Por eso no la escribas ni en archivos que llegan al dispositivo del usuario ni en código que publicas, y cuando se te escape fuera, revócala y emite una clave nueva en lugar de borrar los caracteres que escribiste.
El webhook es el mecanismo por el que el servicio externo llama a tu propio servidor
Que un pago se complete o que haya un reembolso son sucesos cuyo momento quien llama no puede saber.
Preguntar una y otra vez aumenta las llamadas inútiles y retrasa el momento en que te enteras.
El webhook (webhook: el mecanismo por el que, cuando ocurre un suceso determinado, el servicio externo envía una solicitud a una URL registrada) invierte esa dirección.
Solo el webhook de la tercera fila va del servicio de pagos a my-app.
Lo único que preparas es registrar de antemano una URL que reciba los avisos.
Llega un aviso distinto cuando el pago se completa, cuando se crea el recibo y cuando hay un reembolso.
De qué suceso es cada aviso está escrito en el cuerpo de la solicitud.
La flecha 1 es la dirección en la que llamas tú, y la flecha 2 la dirección en la que te llama el servicio externo.
La clave solo llega al servicio de pagos y nunca al dispositivo del usuario.
El webhook es una llamada en sentido contrario
El webhook es la llamada en la que el servicio de pagos llama a my-app.
Sirve para que te avisen en cuanto ocurre un suceso cuyo momento no puedes prever, y lo único que preparas es crear y registrar de antemano una URL que reciba los avisos.
Cualquiera puede llamar a la URL que recibe los avisos, así que comprueba la firma antes de procesar
La URL que recibe los avisos es pública, así que alguien que no sea el servicio de pagos también puede enviar a esa misma URL.
Lo que lo evita es la firma (signature: un valor calculado a partir de una cadena que solo conocen quien envía y quien recibe, que se añade a la solicitud y que quien recibe comprueba haciendo el mismo cálculo).
- POST https://my-app.example.com/webhooks/payment
- La URL que preparaste y registraste
- La firma va aquí
- El ID que distingue un aviso repetido suele ir aquí también
- De qué suceso se trata, escrito en JSON
- El ID del pago y su estado también van aquí
Comprueba la firma de la cabecera antes de leer el contenido.
Cuando no devuelves un éxito, quien envía manda otra vez el mismo aviso: eso es el reenvío (retry).
Registra el ID de cada aviso y salta los que ya procesaste.
La cadena que se usa para la comprobación, igual que la clave de API, no se escribe en el código, y cómo se añade lo compruebas en la documentación de la API.
Cuando un manual dice «verifica la firma», se refiere a esta comprobación.
Comprueba antes de leer y prepárate para una segunda entrega
La URL que recibe los avisos es pública, así que el hecho de que llegue una solicitud no te dice nada de quién la envía.
Comprueba la firma antes de leer el cuerpo y, si coincide, actualiza el registro y devuelve un código de estado de éxito; luego guarda los ID de los avisos que procesaste para saltar una segunda entrega.
Verificación de conocimientos
Responde cada pregunta una a una.
Pregunta 2¿Qué problema hay en escribir una clave de API en código que llega al navegador?
Pregunta 3Cuando llega un aviso por webhook, ¿qué haces antes de leer su contenido?