Sessões e CSRF
Sessão PHP, flash data, old input, token CSRF e cookies seguros.
Session
Framework\Support\Session centraliza start/set/get/has/forget/all/destroy, flash, erros/old input, token CSRF e geração de token criptograficamente aleatório. ageOldInput() faz o ciclo de vida de old input no bootstrap.
CSRF em formulário Web
Middlewares CsrfMiddleware protegem rotas mutáveis Web registradas com eles. Helpers csrf_field() e csrf_token() expõem token em views. Controller injeta campo em forms não-GET renderizados por view(), sem duplicar quando o campo já existe. Para override HTML de PUT/PATCH/DELETE use method_field('PUT') e leia Roteamento.
<form method="POST" action="<?= e(url('posts')) ?>">
<?= csrf_field() ?>
<button type="submit">Salvar</button>
</form>
Cookie e ambiente
Configuração aplica HttpOnly, use_only_cookies e strict mode; a sessão passa explicitamente <code>SameSite=Lax</code>; embora exista <code>SESSION_SAME_SITE</code> na configuração, Session::start() não a aplica. Secure é obrigatório em produção. Configure HTTPS/proxy confiável corretamente antes de depender de esquema encaminhado.
Padrão POST → flash → redirect → GET
Flash é apropriado para feedback de uma única navegação; `Session::getFlash()` lê e remove a mensagem. Old input serve para repopular campos seguros após erro, e o ciclo de aging evita que valores lidos reapareçam em páginas posteriores.
Session::flash('success', 'Registro salvo.');
$this->redirect('dashboard');A função global `flash($key)` é leitora/consumidora na View; o setter é `Session::flash($key,$message)` ou `$this->flash($type,$message)` no Controller. Não confunda os dois nomes parecidos.
Proteção CSRF nos formulários
Associe CsrfMiddleware à rota que altera estado. O template pode incluir explicitamente csrf_field(); Controller::view() também injeta o campo em formulários com method POST/PUT/PATCH/DELETE sem token presente. Forms GET ou sem method não são alterados.
<form method="POST" action="<?= e(url('auth/login')) ?>">
<?= csrf_field() ?>
<input name="email" value="<?= e(old('email')) ?>">
<button type="submit">Entrar</button>
</form>Para um formulário HTML que precisa expressar PUT/DELETE, use `method_field('PUT')`; Request reconhece o override só em POST. O token fica associado à sessão e é comparado com hash_equals.
Opções de cookie realmente aplicadas
Session::start() define SameSite=Lax diretamente. Embora SESSION_SAME_SITE apareça na configuração, essa implementação não lê o valor ao montar as opções do cookie. SESSION_SECURE é considerado fora de produção; em produção Secure é forçado.
Em formulário HTML, passe o método como string: method_field('PUT'). O Request aplica override apenas quando o método original é POST. O campo CSRF pode ser inserido automaticamente por Controller::view() em forms mutáveis, mas a rota também precisa do middleware CSRF.
Flash é read-once quando consultado, não expira sozinho
Session::flash(string $key, string $message): void grava a mensagem na sessão. Session::getFlash(string $key): ?string lê e remove a chave naquele acesso; portanto, duas leituras do mesmo flash não devolvem a mesma mensagem. Por outro lado, mensagens nunca lidas não têm expiração automática nessa implementação. Leia-as/limpe-as nos layouts e handlers apropriados e não use flash como armazenamento durável nem para segredos.
$notice = \Framework\Support\Session::getFlash('success');
if ($notice !== null) {
echo e($notice);
}