# Protege formularios y peticiones con tokens CSRF

> Crea un token con $.csrf(), envíalo con la petición y verifícalo en un middleware para rechazar las peticiones de otros sitios.

Framework: total5
Product: Total.js 5 (total5@0.0.19)
Language: es
Content-SHA256: 749e595973765a0c2e63c56ee6fe82417bbfd11f24654d7c1ea706aa72e7701a
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: total5-installed@total5@0.0.19
Review: not-recorded

Un ataque CSRF hace que el navegador de un usuario con sesión iniciada envíe una petición que nunca quiso hacer. La defensa es un token que la página recibe de tu servidor y que debe volver con cada petición que cambie datos. Total.js crea y verifica el token por ti, pero solo cuando `secret_csrf` está definido en el archivo `config` (sin él la comprobación siempre pasa).

`$.csrf()` devuelve un token (y `@{csrf}` lo imprime en una vista). Es un valor cifrado ligado a la **dirección IP** y al **user agent** del cliente, y caduca pasado el tiempo de `$csrfexpiration` (30 minutos por defecto). `DEF.onCSRFcheck($)` verifica el token que ha vuelto, leído de la cabecera `x-csrf-token` o del parámetro `csrf` de la query string, y devuelve `true` o `false`. En las rutas normales lo llamas tú, y lo más cómodo es hacerlo desde un middleware que añades con `#csrf` a cada ruta que modifica datos. Las rutas WebSocket con el flag `@csrf` se comprueban automáticamente.

```text config
secret_csrf : change-this-secret-in-production
```

```js definitions/csrf.js
MIDDLEWARE('csrf', function($, next) {
	if (DEF.onCSRFcheck($))
		next();
	else
		$.invalid(403);
});
```

```js controllers/csrf.js
exports.install = function() {
	ROUTE('GET /form/', form);
	ROUTE('POST /transfer/ @json #csrf', transfer);
};

function form($) {
	$.json({ csrf: $.csrf() });
}

function transfer($) {
	$.json({ ok: true, amount: $.body.amount });
}
```
