# Proteger formulários e pedidos com tokens CSRF

> Crie um token com $.csrf(), envie-o com o pedido e verifique-o num middleware para rejeitar pedidos vindos de outros sites.

Framework: total5
Product: Total.js 5 (total5@0.0.19)
Language: pt
Content-SHA256: 8da134c858feea80023a9586cfcd748000047d7ebe207f1499a982c14bcd78b1
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: total5-installed@total5@0.0.19
Review: not-recorded

Um ataque CSRF faz com que o navegador de um utilizador autenticado envie um pedido que nunca pretendeu. A defesa é um token que a página recebe do seu servidor e que tem de voltar com cada pedido que altere dados. O Total.js cria e verifica o token por si, mas só quando `secret_csrf` está definido no ficheiro `config` (sem ele a verificação passa sempre).

`$.csrf()` devolve um token (e `@{csrf}` imprime-o numa vista). É um valor cifrado associado ao **endereço IP** e ao **user agent** do cliente, e expira passado o tempo de `$csrfexpiration` (30 minutos por omissão). `DEF.onCSRFcheck($)` verifica o token que voltou, lido do cabeçalho `x-csrf-token` ou do parâmetro `csrf` da query string, e devolve `true` ou `false`. Nas rotas normais é você que o chama, e o mais cómodo é fazê-lo a partir de um middleware que acrescenta com `#csrf` a cada rota que modifica dados. As rotas WebSocket com a flag `@csrf` são verificadas automaticamente.

```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 });
}
```
