POST /auth/refresh
Rotacionar tokens via refresh cookie
/auth/refreshAuth: refreshCookieLê o cookie HttpOnly refreshToken, valida contra refresh_tokens.token_hash, deleta o registro corrente, insere um novo, e retorna um novo access token + um novo cookie. Isso é a rotação clássica — cada refresh "queima" o token anterior.
Use sempre que um request normal voltar 401. O frontend deve interceptar globalmente (ex: Axios/fetch interceptor): se 401, chamar /auth/refresh, e re-executar o request original com o novo access token.
Quando chamar
- Quando um request retorna
401por access token expirado - Na inicialização do frontend (mount), pra restaurar sessão silenciosa: se o cookie ainda for válido, o user é re-logado sem ver tela de login. Se 401, redireciona pra
/login. - Não precisa chamar antes de cada request "preventivamente" — o JWT carrega
expe o frontend pode comparar local-side, mas é simples deixar o backend rejeitar e reagir ao 401.
Request
Esta requisição não tem corpo.
Cookie obrigatório: refreshToken. Setado por login/register/refresh anteriores. Se ausente, o backend retorna 401 imediatamente sem nem consultar o DB.
Response
200
| Campo | Tipo | Requerido | Descrição |
|---|---|---|---|
| accessToken | string | sim |
401
| Campo | Tipo | Requerido | Descrição |
|---|---|---|---|
| error | string | sim | Mensagem ou código tipado do erro. Códigos canônicos: EMAIL_ALREADY_EXISTS, INVALID_CREDENTIALS, INVALID_RESET_TOKEN, PASSWORD_ALREADY_SET, USER_NOT_FOUND. |
Apenas accessToken — diferente de /login e /register, NÃO retorna o objeto user. O frontend pode reusar o user em cache.
O cookie de refresh é rotacionado no header de resposta — o navegador atualiza automaticamente.
Erros
| Status | Códigos possíveis (extraídos do schema) |
|---|---|
| 401 | Mensagem ou código tipado do erro |
Como resolver cada caso:
| Status | Mensagem retornada hoje (legacy PT) | Causa | Como resolver |
|---|---|---|---|
| 401 | "Não autorizado" | Cookie ausente | Redirecione pra login |
| 401 | "Sessão expirada" | Token não bate (já foi consumido / nunca existiu / expirou) | Limpe cache local e redirecione pra login |
⚠️ Race condition em rotação: duas tabs do mesmo navegador podem chamar /auth/refresh simultaneamente. O backend processa em ordem; uma das tabs vai pegar o registro deletado e falhar com 401. Comportamento aceito — a tab perdedora cai pro login. Mitigação no frontend: serializar refresh entre tabs via BroadcastChannel ou lock no localStorage (não implementado).
Exemplos
curl -X POST 'http://localhost:3003/auth/refresh' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer SEU_ACCESS_TOKEN' \
-d '{}'await fetch('http://localhost:3003/auth/refresh', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + accessToken,
},
body: JSON.stringify({}),
})Resposta de sucesso (200)
{
"accessToken": "eyJhbGc..."
}E no Set-Cookie:
refreshToken=novo_64_hex; Path=/; HttpOnly; SameSite=Lax; Expires=Mon, 06 May 2026 12:00:00 GMTSide effects
- DB:
DELETE FROM refresh_tokens WHERE token_hash = sha256(rawCookie)— o token antigo deixa de existir - DB:
INSERT INTO refresh_tokens (...)— novo token rotacionado - Cookie:
Set-Cookieatualiza o navegador - Sem notificações ou eventos de socket
Relacionados
- Conceito: Autenticação — explicação detalhada da rotação
- Módulo: Auth — sequence diagram
- Endpoint:
POST /auth/login— onde a sessão começa - Endpoint:
POST /auth/logout— encerrar antes de expirar - Tabela:
refresh_tokens— onde o token vive