Google reCAPTCHA v3 en Angular SSR con validación backend segura

¿Alguna vez has entrado en un sitio web y al rellenar algún formulario fue necesario "demostrar" que eres un ser humano a través de un prueba?

Esa validación con texto ligeramente distorsionado o selección de imágenes se conoce como reCAPTCHA, un recurso de seguridad de Google diseñado para proteger sitios web contra spam y actividades abusivas, distinguiendo a los humanos de los bots automatizados.

En este artículo explicamos el flujo de reCAPTCHA paso a paso en Angular con verificación backend. Los ejemplos originales usan Angular Universal y NgModule; en aplicaciones nuevas se habla de Angular SSR y son habituales los componentes standalone.

Resumen indexable

La idea importante de esta implementacion es que el navegador solo obtiene un token temporal de reCAPTCHA. La verificacion definitiva debe hacerse en el backend, donde se guarda la clave privada y donde se puede decidir si se acepta el formulario o la accion de API.

Si estas creando un proyecto Angular mas reciente, compara tambien hCaptcha en Angular con validacion backend y Cloudflare Turnstile con Angular y FastAPI. Para APIs que no deben exponer credenciales al navegador, revisa el patron de proxy seguro con Nginx y FastAPI.

En una integracion actual de reCAPTCHA, cada token debe tratarse como temporal y de un solo uso: Google documenta una ventana de validacion de dos minutos, y el backend debe llamar a siteverify antes de aceptar la accion protegida. En Angular moderno, especialmente con standalone o SSR, la clave publica puede estar en Angular, pero la clave secreta debe quedarse solo en el backend.

Los ejemplos antiguos con ng-recaptcha de este articulo sirven para entender el flujo, pero antes de usarlos en una version nueva de Angular conviene comprobar compatibilidad del paquete. Si buscas una alternativa reciente con poca friccion visible, compara el mismo patron de verificacion backend con Cloudflare Turnstile.

Lista de comprobación para reCAPTCHA v3 en producción

  • Genera el token justo antes de la acción protegida y verifícalo una sola vez, dentro de los dos minutos siguientes.
  • Envía el token en el cuerpo de la petición mediante HTTPS; nunca incluyas la clave secreta ni una credencial reutilizable en Angular.
  • En el backend exige success, el hostname esperado y la action prevista. En v3, evalúa la puntuación con umbrales obtenidos a partir de tu propio tráfico.
  • Rechaza tokens duplicados, caducados o mal formados y registra los códigos de error sin almacenar datos personales innecesarios.
  • Combina reCAPTCHA con rate limiting, validación de entrada, autorización y reglas de negocio. Un CAPTCHA es una señal de riesgo, no sustituye la seguridad de la API.
  • Utiliza claves distintas para desarrollo y producción, supervisa las cuotas y ofrece un reintento comprensible cuando falle la validación.

Referencias oficiales: verificación del token en servidor, acciones y puntuación de reCAPTCHA v3 y configuración actual de HttpClient en Angular.

Os dejo el repositorio https://github.com/al118345/angular_recaptcha_gooogle para su consulta y el siguiente video explicativo:

Alta en google.

En este artículo partimos con la premisa de que posees una cuenta de Gmail.

El primer paso es darse de alta en la url https://www.google.com/recaptcha/admin/create. Una vez accedemos y estemos logueados en la cuenta de Gmail aparecerá el siguiente formulario a rellenar.

Importante: Realizar dos inscripciones, una para el dominio escogido y otra con localhost con el objetivo de realizar las pruebas previas a la puesta en producción.

Formulario de alta de reCaptcha

Rellenado el formulario aparecerá la siguiente pantalla con la información acerca de la clave para utilizar el servicio.

Claves generadas de reCaptcha

Implementación histórica con HttpClientModule de Angular

Esta sección conserva el ejercicio original con NgModule y ng-recaptcha. En un proyecto nuevo, comprueba la compatibilidad del paquete con tu versión de Angular, configura HTTP mediante la API actual de providers y no ocultes conflictos de dependencias con --force.

Primero de todo, a través del link al siguiente repositorio https ://github.com/al118345/angular_recaptcha_gooogle/tree/main/src/app/components/asincrono puedes acceder a un ejemplo de este tipo de comunicación. Con respecto al backend tienes el siguiente ejemplo en el repositorio https://github.com/al118345/TestComunicacionApiRest_Angular

Para realizar esta instalación, hay que dividir el proyecto entre un front-end y un back-end. Dentro del front-end, en esta parte del proyecto hemos escogido utilizar una librería de Angular que permite realizar comunicaciones con el back-end. La librería se llama HttpClient.

El material original también comparaba este enfoque con un paquete XMLHttpRequest. En aplicaciones web actuales se utiliza normalmente el cliente HTTP del framework o fetch; el ejemplo síncrono de la sección siguiente se conserva únicamente para explicar la evolución de la implementación.

Dicho esto, con HttpClientModule realizaremos una comunicación asíncrona. El front realizará la interacción con el usuario y el backend se comunicará con Google pero el usuario no percibe dicho trabajo. La navegación no se detiene y puedes, por ejemplo, mostrar un código de esperando la respuesta en la web.

Desde Angular realizaremos la instalación del paquete ng-recaptcha con el siguiente comando:

Además crearemos el siguiente servicio para comunicarse con la api de Python.

Importamos el módulo a nuestra app con el siguiente código:
Y añadiremos la funcionalidad en el componente:

Por último, modificamos la api para recibir la petición del front-end creando la siguiente ruta en el proyecto https://github.com/al118345/envio_email_api_python
Para terminar, en la web https://www.google.com/u/3/recaptcha/admin/ puedes consultar una vista como la siguiente imagen dónde puedes comprobar la cantidad de gente que ha realizado el login y la puntuación obtenida de media.
Panel de control de reCaptcha

Ejemplo en ejecución presionando un botón

Ejemplo de ejecución HttpClient(asíncrona) de google recaptcha

¿Eres un robot?. Según recaptcha de Google de momento eres un:

Eres un robot

Implementación histórica síncrona con XMLHttpRequest

No uses XMLHttpRequest síncrono en una aplicación web nueva: bloquea el hilo principal y perjudica la usabilidad. Esta sección completa se conserva como ejercicio histórico; en producción utiliza HttpClient o fetch de forma asíncrona y muestra estados claros de carga, reintento y error.

Importante, con esta instalación la ejecución de vuestra web se detendrá hasta obtener el resultado del captcha. Es decir, no puede mostrar un cartel de cargando o realizando ningún tipo de scroll.

Primero de todo, a través del link al siguiente repositorio https ://github.com/al118345/angular_recaptcha_gooogle/tree/main/src/app/components/sincrono puedes acceder a un ejemplo de este tipo de comunicación. Con respecto al backend tienes el siguiente ejemplo en el repositorio https://github.com/al118345/TestComunicacionApiRest_Angular

Para realizar esta instalación, hay que dividir el proyecto entre un front-end y un back-end. El front realizará la interacción con el usuario y el backend se comunicará con Google.

Desde Angular realizaremos la instalación del paquete ng-recaptcha con el siguiente comando:

Además crearemos el siguiente servicio para comunicarse con la api de Python.

Importamos el módulo a nuestra app con el siguiente código:
Y añadiremos la funcionalidad en el componente:

Por último, modificamos la api para recibir la petición del front-end creando la siguiente ruta en el proyecto https://github.com/al118345/envio_email_api_python
Para terminar, en la web https://www.google.com/u/3/recaptcha/admin/ puedes consultar una vista como la siguiente imagen dónde puedes comprobar la cantidad de gente que ha realizado el login y la puntuación obtenida de media.
Panel de control de reCaptcha

Ejemplo en ejecución

Ejemplo de ejecución XmlHttpRequest(síncrona) de google recaptcha

¿Eres un robot?. Según recaptcha de Google:

Eres un robot