O percurso de ponta a ponta
[Front] login(usuario, senha)
│ POST /login { usuario, senha }
▼
[Back] valida credenciais ──> emite token assinado (com exp)
│ 200 { token }
▼
[Front] guarda o token e o anexa em cada requisição:
│ GET /perfil Authorization: Bearer <token>
▼
[Back] verifica o token ──> sabe quem você é ──> responde
Passo a passo
- Login: o usuário envia
usuarioesenha. O backend verifica a senha (contra o hash guardado, nunca contra a senha em texto plano). - Emissão: se estiver correta, o backend emite uma credencial: um token
assinado (JWT) ou um id de sessão. Inclui uma validade (
exp). - Guardado no front: o frontend guarda a credencial (cookie ou
localStorage). - Anexar: em cada requisição posterior o front envia a credencial. Com
JWT, no cabeçalho
Authorization: Bearer <token>. - Verificação: o backend lê o cabeçalho, verifica a assinatura e a
validade, e carrega o usuário (p. ex. em
req.usuario). - Rotas protegidas: um middleware corta o caminho com 401 se não houver credencial válida, antes de chegar ao handler.
Expiração e refresh tokens
Um token de acesso deve durar pouco (minutos): se for roubado, o dano caduca logo. Mas pedir ao usuário que faça login de novo a cada 15 minutos é horrível. Solução: dois tokens.
- Access token: vida curta, anexado em cada requisição.
- Refresh token: vida longa, guardado com mais cuidado e usado apenas para pedir um novo access token quando o anterior caduca, sem novo login.
Assim você combina segurança (janela de roubo pequena) e comodidade (sessões longas sem incomodar o usuário).
Exemplos
Ler 'Bearer <token>' do cabeçalho Authorization
const headers = { Authorization: "Bearer abc.def.ghi" };
const cabecalho = headers.Authorization || "";
const [esquema, token] = cabecalho.split(" ");
console.log(esquema, token); // Bearer abc.def.ghi