Toolypet
Voltar ao Blog
Dev

Guia Completo de JWT 2026 - Estrutura, Seguranca e Melhores Praticas

Da estrutura e funcionamento do JSON Web Token a vulnerabilidades de seguranca e melhores praticas. Domine a autenticacao JWT com exemplos de codigo praticos.

Toolypet Team

Toolypet Team

Development Team

9 min de leitura

Guia Completo de JWT 2026

"JWT? Nao e apenas um token?"

Sim, e. Mas quando esse "simples token" nao e implementado corretamente, torna-se um problema serio de seguranca. De acordo com estudos de 2026, 48% do codigo de autenticacao gerado por IA contem vulnerabilidades de seguranca.

Este guia cobre tudo, desde a estrutura do JWT ate as melhores praticas de seguranca.


O que e JWT?

JWT (JSON Web Token) e um metodo compacto e autocontido para transmitir informacoes de forma segura entre duas partes.

Caracteristicas Principais

CaracteristicaDescricao
StatelessNao requer armazenamento de sessao no servidor
Self-containedToda informacao necessaria esta no token
CompactUtilizavel em URLs, headers HTTP
SignedPode detectar adulteracao

Casos de Uso

  • Autenticacao API: Requisicoes API com Bearer token
  • SSO (Single Sign-On): Compartilhar autenticacao entre multiplos servicos
  • Troca de informacoes: Transmissao de dados assinados
  • Authorization: Incluir informacoes de permissoes/roles

Estrutura do JWT

JWT consiste em tres partes codificadas em Base64URL separadas por . (pontos).

xxxxx.yyyyy.zzzzz
  |      |      |
Header  Payload  Signature

1. Header

{
  "alg": "HS256",
  "typ": "JWT"
}
CampoDescricao
algAlgoritmo de assinatura (HS256, RS256, etc.)
typTipo de token (JWT)

2. Payload (Claims)

{
  "sub": "user123",
  "name": "Joao Silva",
  "email": "joao@example.com",
  "role": "admin",
  "iat": 1708502400,
  "exp": 1708588800
}

Claims Registrados

ClaimDescricaoExemplo
issEmissor (Issuer)"https://auth.example.com"
subSujeito (Subject)"user123"
audAudiencia (Audience)"https://api.example.com"
expTempo de expiracao1708588800
nbfNao antes de (Not Before)1708502400
iatEmitido em (Issued At)1708502400
jtiID unico do JWT"abc123"

Claims Publicos/Privados

{
  "role": "admin",           // Claim privado
  "email": "user@example.com",
  "permissions": ["read", "write"]
}

3. Signature

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)

Algoritmos de Assinatura

Chave Simetrica

AlgoritmoDescricaoCaso de Uso
HS256HMAC + SHA-256Servidor unico, implementacao simples
HS384HMAC + SHA-384Maior seguranca
HS512HMAC + SHA-512Seguranca de nivel maximo
// Node.js - HS256
const jwt = require('jsonwebtoken');

const token = jwt.sign(
  { userId: 123, role: 'admin' },
  'your-256-bit-secret',  // Verificado com o mesmo segredo
  { algorithm: 'HS256', expiresIn: '1h' }
);

Chave Assimetrica

AlgoritmoDescricaoCaso de Uso
RS256RSA + SHA-256Microsservicos, verificacao publica
RS384RSA + SHA-384Requisitos de alta seguranca
RS512RSA + SHA-512Seguranca de nivel maximo
ES256ECDSA + P-256Chaves curtas, movel
// RS256 - Assimetrico
const privateKey = fs.readFileSync('private.pem');
const publicKey = fs.readFileSync('public.pem');

// Emissao (Private Key)
const token = jwt.sign(payload, privateKey, { algorithm: 'RS256' });

// Verificacao (Public Key)
const decoded = jwt.verify(token, publicKey, { algorithms: ['RS256'] });

Guia de Selecao de Algoritmo

CenarioAlgoritmo Recomendado
Servidor unicoHS256
MicrosservicosRS256
Verificacao publica necessariaRS256 / ES256
Movel/IoTES256 (chaves curtas)

Implementacao Pratica

Node.js (Express)

const express = require('express');
const jwt = require('jsonwebtoken');

const app = express();
const SECRET = process.env.JWT_SECRET; // Carregar da variavel de ambiente

// Emissao de token
app.post('/login', async (req, res) => {
  const { email, password } = req.body;

  // Verificacao de usuario (exemplo)
  const user = await verifyCredentials(email, password);
  if (!user) {
    return res.status(401).json({ error: 'Invalid credentials' });
  }

  const token = jwt.sign(
    {
      sub: user.id,
      email: user.email,
      role: user.role,
    },
    SECRET,
    {
      expiresIn: '1h',
      issuer: 'your-app-name',
    }
  );

  res.json({ token });
});

// Verificacao com middleware
const authMiddleware = (req, res, next) => {
  const authHeader = req.headers.authorization;

  if (!authHeader?.startsWith('Bearer ')) {
    return res.status(401).json({ error: 'Missing token' });
  }

  const token = authHeader.split(' ')[1];

  try {
    const decoded = jwt.verify(token, SECRET, {
      issuer: 'your-app-name',
      algorithms: ['HS256'],
    });
    req.user = decoded;
    next();
  } catch (err) {
    return res.status(401).json({ error: 'Invalid token' });
  }
};

// Rota protegida
app.get('/protected', authMiddleware, (req, res) => {
  res.json({ message: `Hello, ${req.user.email}` });
});

Python (FastAPI)

from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
import jwt
from datetime import datetime, timedelta
import os

app = FastAPI()
security = HTTPBearer()
SECRET = os.environ.get("JWT_SECRET")

# Emissao de token
def create_token(user_id: str, role: str) -> str:
    payload = {
        "sub": user_id,
        "role": role,
        "iat": datetime.utcnow(),
        "exp": datetime.utcnow() + timedelta(hours=1),
    }
    return jwt.encode(payload, SECRET, algorithm="HS256")

# Verificacao de token
def verify_token(credentials: HTTPAuthorizationCredentials = Depends(security)):
    token = credentials.credentials
    try:
        payload = jwt.decode(token, SECRET, algorithms=["HS256"])
        return payload
    except jwt.ExpiredSignatureError:
        raise HTTPException(status_code=401, detail="Token expired")
    except jwt.InvalidTokenError:
        raise HTTPException(status_code=401, detail="Invalid token")

# Endpoint protegido
@app.get("/protected")
def protected_route(user: dict = Depends(verify_token)):
    return {"message": f"Hello, {user['sub']}"}

Vulnerabilidades de Seguranca e Contramedidas

1. Ataque Algorithm None

// Header malicioso
{
  "alg": "none",
  "typ": "JWT"
}

Contramedida:

// Especificar algoritmos permitidos
jwt.verify(token, secret, { algorithms: ['HS256'] }); // OK
jwt.verify(token, secret); // Perigoso

2. Chave Secreta Fraca

// Perigoso
const SECRET = 'secret123';

// Seguro (minimo 256 bits)
const SECRET = crypto.randomBytes(32).toString('hex');

3. Exposicao de Informacoes Sensiveis

// Perigoso: Payload pode ser decodificado em Base64
{
  "password": "user_password",  // Nunca faca isso!
  "creditCard": "1234-5678-9012-3456"
}

// Seguro
{
  "sub": "user123",
  "role": "admin"
}

4. Roubo de Token

Estrategias de contramedida:

  • Tempo de expiracao curto (15 min ~ 1 hora)
  • Usar Refresh Token
  • HTTPS obrigatorio
  • Cookies HttpOnly (prevencao XSS)

5. Ataque de Replay JWT

// Usar jti (JWT ID)
const token = jwt.sign({
  sub: user.id,
  jti: crypto.randomUUID(), // ID unico
}, SECRET);

// Gerenciar lista negra de jti no servidor

Access Token + Refresh Token

Por que e necessario?

TokenDuracaoProposito
Access Token15 min ~ 1 horaAutenticacao API
Refresh Token7 ~ 30 diasRenovar Access Token

Exemplo de Implementacao

// Emitir ambos tokens no login
app.post('/login', async (req, res) => {
  const user = await verifyCredentials(req.body);

  const accessToken = jwt.sign(
    { sub: user.id, type: 'access' },
    ACCESS_SECRET,
    { expiresIn: '15m' }
  );

  const refreshToken = jwt.sign(
    { sub: user.id, type: 'refresh' },
    REFRESH_SECRET,
    { expiresIn: '7d' }
  );

  // Refresh Token como cookie HttpOnly
  res.cookie('refreshToken', refreshToken, {
    httpOnly: true,
    secure: true,
    sameSite: 'strict',
    maxAge: 7 * 24 * 60 * 60 * 1000,
  });

  res.json({ accessToken });
});

// Renovacao de token
app.post('/refresh', (req, res) => {
  const refreshToken = req.cookies.refreshToken;

  try {
    const decoded = jwt.verify(refreshToken, REFRESH_SECRET);

    const newAccessToken = jwt.sign(
      { sub: decoded.sub, type: 'access' },
      ACCESS_SECRET,
      { expiresIn: '15m' }
    );

    res.json({ accessToken: newAccessToken });
  } catch (err) {
    res.status(401).json({ error: 'Invalid refresh token' });
  }
});

Depuracao de JWT

Decodificacao de Token

Cole seu token no JWT Decoder para:

  • Verificar Header
  • Verificar Payload
  • Verificar tempo de expiracao
  • Verificar assinatura (quando segredo e fornecido)

Decodificacao CLI

# Decodificar Header
echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9" | base64 -d

# Decodificar Payload
echo "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4ifQ" | base64 -d

Lista de Verificacao de Melhores Praticas

Emissao

  • Chave secreta forte (256 bits ou mais)
  • Especificar algoritmo (HS256, RS256)
  • Tempo de expiracao curto (15 min ~ 1 hora)
  • Incluir claims obrigatorios (sub, iat, exp, iss)
  • Sem informacoes sensiveis

Verificacao

  • Lista branca de algoritmos (algorithms: ['HS256'])
  • Validacao de tempo de expiracao
  • Validacao de emissor (iss)
  • Validacao de audiencia (aud)

Armazenamento e Transmissao

  • HTTPS obrigatorio
  • Cookie HttpOnly (prevencao XSS)
  • Atributo SameSite (prevencao CSRF)
  • Evitar localStorage (vulneravel a XSS)

Perguntas Frequentes

Q1: JWT vs Session, quando usar qual?

R:

  • JWT: API stateless, microsservicos, apps moveis
  • Session: Apps web tradicionais, renderizacao do lado do servidor, logout imediato necessario

Q2: E se o JWT for roubado?

R: Access Token permanece valido ate expirar. Portanto:

  • Definir tempo de expiracao curto (15 min)
  • Refresh Token Rotation
  • Invalidar todos os tokens quando houver suspeita

Q3: Por que nao devo armazenar em localStorage?

R: E vulneravel a ataques XSS. Como JavaScript pode acessar, scripts maliciosos podem roubar tokens. Cookies HttpOnly sao mais seguros.

Q4: RS256 e mais seguro que HS256?

R: Nao e "mais seguro" mas "proposito diferente".

  • HS256: Mesmo segredo compartilhado, servidor unico
  • RS256: Verificar com chave publica, multiplos servicos

Q5: Preciso de uma lista negra de tokens?

R: Se voce precisa de logout imediato, sim. Mas reduz a vantagem de stateless. Expiracao curta + Refresh Token e uma alternativa.


Conclusao

Pontos-chave de seguranca JWT:

  1. Segredo forte: 256 bits ou mais aleatorios
  2. Verificacao de algoritmo: Abordagem de lista branca
  3. Duracao curta: Access 15 min, Refresh 7 dias
  4. Armazenamento seguro: Cookies HttpOnly + Secure
  5. Sem info sensivel: Payload e decodificavel por qualquer um

Ferramentas Relacionadas

FerramentaProposito
JWT DecoderDecodificacao e verificacao JWT
Base64 EncoderCodificacao/decodificacao Base64
Hash GeneratorGeracao de hash
JWTAutenticacaoSegurancaAPIDesenvolvimento WebToken

Sobre o Autor

Toolypet Team

Toolypet Team

Development Team

The Toolypet Team creates free, privacy-focused web tools for developers and designers. All tools run entirely in your browser with no data sent to servers.

Web DevelopmentCSS ToolsDeveloper ToolsSEOSecurity