Saltar al contenido principal

Altcha

Alternativa de código abierto equivalente a reCaptcha.

Introducción​

La implementación del mecanismo de seguridad con captcha es de suma importancia; a continuación se presentan algunos motivos relevantes:

  • Evitar que los robots realicen accesos automáticos a las direcciones de la API.
  • Garantizar que el acceso lo realiza una persona real.
  • También garantiza que el acceso se ha realizado con un navegador.

Durante mucho tiempo, el mecanismo de captcha ofrecía un desafío que el usuario debía completar.

Hoy en día esto es innecesario, porque se utiliza un mecanismo de claves cifradas combinado con un desafío que debe resolverse mediante un algoritmo que emplea la interacción en el navegador, detectando así si la interacción es humana o robotizada.

Este método es ingenioso y fiable; con un solo clic se detecta si es humano o robot.

Altcha es un proyecto de código abierto que implementa este proceso de seguridad, con un widget de frontend que también se integra con React, y un recurso de backend que ofrece Netuno.

Limitaciones​

Altcha utiliza la Web Crypto API, solo funciona en direcciones HTTPS seguras con certificado SSL, o localmente.

En el frontend, si el dominio no es localhost, la URL obligatoriamente debe ser HTTPS segura con certificado SSL.

Cuando se accede al frontend localmente, los navegadores permiten utilizar la Web Crypto API solo en la dirección local, obligatoriamente localhost; por lo tanto, en caso contrario se exige HTTPS seguro con certificado SSL.

Backoffice​

Para activar la autenticación con Altcha en el backoffice de su aplicación Netuno, utilice la siguiente configuración en la aplicación:

config/_[ENTORNO].json
{
...
"auth": {
"altcha": {
"admin": {
"enabled": true
}
}
},
...
}

Listo, ahora basta con acceder a la pantalla de inicio de sesión del backoffice y ya verá la casilla de verificación de Altcha en pleno funcionamiento.

Cómo funciona​

Netuno proporciona en la API REST un servicio estándar que proporciona los parámetros de Altcha al frontend; normalmente, la dirección de este servicio es:

  • http://localhost:9000/services/_altcha

Con los parámetros, el widget de Altcha en el frontend genera el resultado del desafío firmado digitalmente, que se envía al backend en el campo oculto altcha del formulario.

En el backend se valida si el resultado y la firma digital son realmente correctos.

Widget en HTML​

Ejemplo de cómo se integra el widget en el HTML de inicio de sesión del backoffice:

inicio-sesion.html
<script type="text/javascript" src="/scripts/plugins/altcha/altcha.i18n.umd.min.cjs"></script>
<form ...>
<input id="entradaAltcha" type="hidden" name="altcha" value="">
<altcha-widget id="widgetAltcha"
challenge="/services/_altcha" language="es"
hideLogo hideFooter></altcha-widget>
<script>
document.getElementById("widgetAltcha").addEventListener("statechange", function (e) {
if (e.detail.state === "verified") {
document.getElementById("entradaAltcha").value = e.detail.payload;
}
}, false);
</script>
...
</form>

Tenga en cuenta que la URL utilizada en el atributo challenge del widget es el servicio autogenerado por Netuno con la parametrización del desafío.

Autenticación externa​

La autenticación normalmente implementada y segura con JWT utiliza el servicio estándar de la API REST para autenticación, que suele ser:

  • http://localhost:9000/services/_auth

Este servicio autogenerado por Netuno permite garantizar la seguridad para la autenticación externa con JWT nativo, pero también realiza la validación del resultado del desafío del widget de captcha.

Para activar Altcha en la autenticación, añada la configuración:

config/_[ENTORNO].json
{
...
"auth": {
"altcha": {
"enabled": true
}
},
...
}

Así, solo las solicitudes de autenticación, es decir, los inicios de sesión que envíen la clave del resultado del desafío generado por Altcha y que sea válida, podrán autenticarse correctamente; en caso contrario, el inicio de sesión será bloqueado.

Se debe integrar en el frontend el widget de Altcha y enviar la clave del resultado del desafío en el campo altcha.

Widget en React​

Vea a continuación cómo realizar la integración del widget en React:

Añada la dependencia de Altcha:

  • bun add altcha

Importe Altcha en el código:

website/src/pages/InicioSesion/index.jsx
import "altcha/i18n";

Cree el estado para almacenar la clave del resultado del desafío:

website/src/pages/InicioSesion/index.jsx
const [cargaAltcha, setCargaAltcha] = useState(null);

Cree una referencia interna en el componente React para el widget:

website/src/pages/InicioSesion/index.jsx
const altcha = useRef(null);

Añada el efecto de carga del componente que utiliza la referencia del widget, con un evento que observa cuándo se hace clic en la casilla de verificación del widget para cargar la clave del resultado del desafío en el estado:

website/src/pages/InicioSesion/index.jsx
useEffect(() => {
if (altcha && altcha.current) {
function altchaVerificado(ev) {
if (ev.detail.state === "verified") {
setCargaAltcha(ev.detail.payload);
}
}
altcha.current.addEventListener("statechange", altchaVerificado, false);
return () => {
if (altcha.current != null) {
altcha.current.removeEventListener("statechange", altchaVerificado, false);
}
}
}
}, [altcha]);

Ejemplo del widget en el "HTML" del componente React:

website/src/pages/InicioSesion/index.jsx
<altcha-widget
ref={altcha}
challenge={_service.url('/_altcha')}
language="es"
delay={1}
hideLogo={true}
hideFooter={true}
></altcha-widget>

Auth Client​

Vea cómo integrar Altcha en el Auth Client.

Utilice el código siguiente en el evento que envía los datos del formulario de inicio de sesión al backend, como los eventos onSubmit, onClick o el onFinish de los formularios de Ant.Design:

website/src/pages/InicioSesion/index.jsx
_auth.login({
username,
password,
data: (data) => {
data.altcha = cargaAltcha;
return data;
},
success: ({json}) => {
...
},
fail: (data) => {
...
}
});

Tenga en cuenta que cargaAltcha es el estado que contiene la clave del resultado del desafío del captcha.

Ejemplo completo en la página de inicio de sesión de ReAuthKit:

Integración en servicios​

Además de la autenticación, como hemos visto anteriormente, en cualquier otro tipo de servicio se puede integrar el mecanismo de captcha con Altcha.

Se recomienda integrar el captcha en cualquier servicio público que pueda ser objetivo de ataques, como la automatización exhaustiva de robots para el registro masivo de datos.

En el frontend, en la pantalla en la que se integra el servicio de la API REST, también debe implementarse el widget de seguridad de Altcha; es decir, donde se llama al servicio debe utilizarse el widget.

Service Client​

Vea a continuación cómo integrar Altcha en el Service Client.

La integración del widget en el frontend es similar a lo ya explicado anteriormente en:

Necesitamos obtener el payload del widget, exactamente como se ha ejemplificado anteriormente; se sigue el mismo proceso que en la autenticación de inicio de sesión.

El payload se envía al backend mediante un parámetro en la URL, un campo del formulario o como una propiedad en el JSON, dependiendo del método HTTP y de cómo se implemente el servicio.

Ejemplo de cómo enviar el payload al servicio de registro, o alta de una nueva cuenta de usuario:

pages/Registro/index.jsx
_service({
method: 'POST',
url: 'registro',
data: {
name,
email,
password,
altcha: cargaAltcha
},
success: (response) => {
...
},
fail: (e) => {
...
}
});

Tenga en cuenta que cargaAltcha es el estado que contiene la clave del resultado del desafío del captcha.

Ejemplo completo en la página de Registro de ReAuthKit:

Backend​

Con el payload enviado al servicio de la API REST, en el código del servicio, en el lado del backend, tenemos que validarlo; vea cómo:

server/services/registro/post.js
const cargaAltcha = _req.getString("altcha");

if (_auth.altchaEnabled() && !_altcha.verifySolution(cargaAltcha)) {
_header.status(409);
_out.json(
_val.map()
.set("error", "carga-altcha-invalida")
);
_exec.stop();
}

Ejemplo completo del servicio de Registro de ReAuthKit:

Vea más sobre los recursos de programación low-code y políglota:

Conclusión​

De forma bastante simplificada podemos crear un mecanismo de seguridad en los servicios de la API para evitar robots y garantizar la interacción por parte de humanos en el navegador.

Se recomienda utilizar el mecanismo de captcha con Altcha en los servicios públicos más sensibles, como los servicios de registro y autenticación.

Con la implementación nativa que ofrece Netuno, resulta muy sencillo activar y utilizar este mecanismo en cualquier servicio de la API REST.

Se recomienda que el backoffice autogenerado de Netuno siempre tenga la autenticación con Altcha activada en producción, y con HTTPS y certificado SSL.

Siempre que sea posible, utilice Altcha para garantizar seguridad y robustez a los servicios públicos de su API.