DevGuideTK
← Trilha Backend

Sessão, JWT e OAuth2

As três formas mais comuns de identificar o usuário a cada pedido, com as trocas de cada uma.

Em produção, a autenticação quase sempre passa pelo framework ou por um provedor. Os exemplos abaixo usam a biblioteca de JWT mais adotada em cada linguagem, para deixar visíveis as verificações que o framework faz por você e que um código escrito às pressas esquece.

Emitir e validar um JWT

O token leva o identificador do usuário (sub), quem o emitiu (iss), para quem ele vale (aud) e quando vence (exp). A validação confere a assinatura e cada um desses campos, e aceita um único algoritmo.

import { SignJWT, jwtVerify } from "jose";

const segredo = new TextEncoder().encode(process.env.JWT_SECRET);
const EMISSOR = "https://api.loja.com.br";
const PUBLICO = "loja-web";

export async function emitirToken(usuarioId: string) {
  return new SignJWT({ papel: "cliente" })
    .setProtectedHeader({ alg: "HS256" })
    .setSubject(usuarioId)
    .setIssuer(EMISSOR)
    .setAudience(PUBLICO)
    .setIssuedAt()
    .setExpirationTime("15m")
    .sign(segredo);
}

export async function validarToken(token: string) {
  const { payload } = await jwtVerify(token, segredo, {
    algorithms: ["HS256"],
    issuer: EMISSOR,
    audience: PUBLICO,
  });
  return payload;
}

O que muda de uma linguagem para outra

BibliotecaExige escolher o algoritmo na validaçãoConfere exp sozinha
NodejoseNão, mas aceitar só um é recomendadoSim
PythonPyJWTSim: algorithms é obrigatórioSim
Gogolang-jwt/jwt v5Não, mas WithValidMethods é recomendadoSim quando presente; WithExpirationRequired exige que exista
Javajjwt 0.12Não; o algoritmo segue o tipo da chaveSim
C#Microsoft.IdentityModelNão, mas ValidAlgorithms é recomendadoSim

Em ASP.NET, Spring Security e nos middlewares de Express, FastAPI e Go, essa mesma validação é configurada uma vez, e cada rota recebe o usuário já identificado. Os nomes mudam; os campos conferidos são os mesmos.

HS256 ou RS256

AlgoritmoChaveQuem consegue emitirQuando usar
HS256Um segredo compartilhadoQualquer um que validaUm único serviço emite e valida
RS256 ou ES256Par de chaves: privada assina, pública validaSó quem tem a chave privadaVários serviços validam, ou o token vem de um provedor

Com um provedor OIDC, os serviços baixam as chaves públicas do endereço jwks_uri do provedor e validam os tokens sem nenhum segredo compartilhado. As bibliotecas acima aceitam essa configuração e guardam as chaves em cache.

Seja um identificador de sessão ou um token, o cookie que o carrega precisa de quatro atributos:

Set-Cookie: sessao=k3J9xQ2mZ8...; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=86400
AtributoO que fazSem ele
HttpOnlyEsconde o cookie do JavaScriptUm script injetado rouba a sessão
SecureSó envia o cookie por HTTPSO cookie viaja em texto legível numa rede aberta
SameSite=LaxNão envia o cookie em pedidos POST vindos de outros sitesOutro site dispara ações em nome do usuário
Max-AgeDefine quando o cookie expiraO cookie dura até o navegador fechar, ou mais

Duas regras completam o quadro:

  • Gere um novo identificador de sessão no login. Se o identificador anterior ao login continuar valendo, quem o conhecia antes herda a sessão autenticada (fixação de sessão).
  • No logout, apague no servidor. Remover só o cookie do navegador deixa a sessão válida para quem tiver copiado o valor.

Lista de revisão

Tokens

  • A validação confere assinatura, exp, iss e aud, com algoritmo fixo?
  • O token de acesso vence em minutos? Existe renovação com registro e rotação?
  • O segredo tem pelo menos 32 bytes aleatórios e vem do ambiente, fora do código?
  • O token não carrega dado sensível?

Sessões e cookies

  • O cookie tem HttpOnly, Secure, SameSite e expiração?
  • O identificador da sessão é trocado no login?
  • O logout apaga a sessão no servidor?
  • Trocar a senha encerra as outras sessões do usuário?

Fluxo

  • O OAuth2 usa código de autorização com PKCE, e não os fluxos implícito ou de senha?
  • O endereço de retorno do OAuth2 é conferido contra uma lista exata?
  • As tentativas de login têm limite por conta e por endereço?

Prompts para aprofundar

Ao abrir no ChatGPT ou no Claude, o prompt é enviado ao serviço escolhido pela URL e também fica copiado na sua área de transferência.

  • Implementar login com sessão, passo a passo

    Quero implementar um login com sessão do zero, para entender o que os frameworks fazem por mim.
    
    Pergunte em qual linguagem e framework eu quero trabalhar.
    
    Vamos em etapas. Em cada uma, explique o objetivo, deixe que eu tente, e depois mostre a sua versão comentando as diferenças:
    1. Cadastro com a senha guardada com um algoritmo próprio para senhas.
    2. Login que confere a senha, cria a sessão num armazenamento e devolve o cookie com os atributos corretos.
    3. Um middleware que identifica o usuário em cada pedido pelo cookie.
    4. Troca do identificador da sessão no login.
    5. Logout que apaga a sessão no servidor, e encerramento das outras sessões quando a senha muda.
    6. Limite de tentativas de login por conta e por endereço.
    
    Em cada etapa, mostre como testar com curl, incluindo os casos de ataque, e o que observar nos cabeçalhos.
  • Validar tokens de um provedor OIDC

    Quero aprender a validar no meu backend os tokens emitidos por um provedor OpenID Connect.
    
    Pergunte qual linguagem, framework e provedor eu uso.
    
    Explique, com código para o meu caso:
    1. O que é o documento de descoberta do provedor e o endereço jwks_uri.
    2. Como validar a assinatura com as chaves públicas, mantendo as chaves em cache e lidando com a troca de chaves pelo provedor.
    3. Quais campos conferir: iss, aud, exp, nbf e, no token de identidade, nonce.
    4. A diferença entre token de acesso e token de identidade, e por que a API deve aceitar só o token de acesso.
    5. Como extrair o usuário e as permissões do token e entregá-los às rotas.
    
    Depois, me mostre cinco tokens com um defeito cada (vencido, emissor errado, público errado, algoritmo inesperado, assinatura alterada) e pergunte o que a minha validação deve fazer com cada um.
  • Revisar o código de autenticação

    Vou colar abaixo código de autenticação: login, emissão ou validação de token, middleware ou configuração de cookies. Revise com foco em segurança.
    
    Verifique, nesta ordem, e para cada item diga se está correto, incorreto ou ausente, citando a linha:
    1. A senha é guardada com um algoritmo próprio para senhas e comparada de forma segura?
    2. O token é validado, e não apenas decodificado? O algoritmo é fixo? São conferidos exp, iss e aud?
    3. O segredo ou a chave vem do ambiente e tem tamanho adequado?
    4. Onde o token ou a sessão fica guardado no navegador? O cookie tem HttpOnly, Secure, SameSite e expiração?
    5. O identificador de sessão é trocado no login? O logout apaga a sessão no servidor?
    6. Há limite de tentativas de login? As mensagens de erro revelam se o e-mail existe?
    7. Há dado sensível dentro do token ou em logs?
    
    Para cada problema, descreva o ataque possível e mostre a correção. Não reescreva o que já está correto.
    
    Código:
    [cole aqui]