JWT (JSON Web Token): O que é, para que serve e como funciona

Você já participou de um evento em que precisou mostrar um documento de identificação para comprovar sua identidade e ter acesso à entrada?
Esse pedido de identificação é uma forma de autenticação: garante que apenas pessoas autorizadas possam entrar.
Na web, esse processo funciona de forma parecida. Para fazer requisições de alguns serviços ou acessar páginas específicas, você precisa se identificar de alguma forma, e por isso, é utilizado o JSON Web Token, também conhecido como JWT, essencial para autenticação segura de usuários em aplicações web atuais.
Neste artigo, você vai aprender o que é JWT, para que serve um jwt token, como funciona a autenticação jwt (jwt authentication) na prática, além de exemplos, passo a passo e dicas de segurança.
O que é um token?
Atualmente, ouvimos muito a palavra token relacionada a NFTs (sigla para “Tokens não fundíveis” em português), metaverso, criptomoedas, etc. Porém, fora desse contexto, um token pode ser entendido como uma assinatura digital, ou uma chave única de acesso.
Quando você abre uma conta em um banco, você precisa definir uma senha e seus dados pessoais.
Esses dados são convertidos em uma assinatura digital que vai identificar você de forma única para aquele banco e, toda vez que você acessar seu banco e entrar com sua senha e um dado pessoal, o banco entenderá e confirmará que você é aquele usuário logado, semelhante a entrarmos no evento quando apresentamos nosso documento de identidade.
Existem vários algoritmos e padrões que transformam suas informações em um token, isto é, uma chave de autenticação única, que faz sentido para o serviço ou aplicação que esteja tentando acessar no momento. Um desses padrões é o JWT, que é seguro por permitir uma autenticação entre duas partes através de um token assinado.
O que é JWT (JSON Web Token)?
Um JWT é um padrão para autenticação e troca de informações definido pela RFC7519. Nele é possível armazenar de forma segura e compacta objetos JSON. Este token é um código Base64 e pode ser assinado usando um segredo ou par de chaves privadas/públicas.
Tokens assinados podem verificar a integridade das informações contidas neles, diferente de tokens criptografados que ocultam essas informações. Se um JWT é assinado por um par de chaves pública/privada, a assinatura certifica que a parte que possui a chave privada é quem de fato assinou.
Quando e onde eu posso usar um JWT?
Você pode usar, por exemplo, em um cenário de autorização. Depois que o usuário estiver conectado, é possível observar cada solicitação e verificar se esta inclui o JWT, permitindo que o usuário acesse rotas, serviços e outros recursos.
Outro cenário de utilização de JWTs são as trocas de informações pois, como eles são assinados, é possível ter certeza de que os remetentes são quem dizem ser quem são. Além disso, podemos identificar se o conteúdo da assinatura foi alterado ou não devido à composição de um JWT.
Como surgiu o JWT?
Ele faz parte de uma família de especificações: a família JOSE.
JOSE significa JSON Object Signing and Encryption, em português Assinatura e criptografia de objetos JSON. O JWT faz parte dessa família de especificações e representa o token. Abaixo, você confere outras especificações desta família:
- JWT (JSON Web Tokens): representa o token propriamente dito;
- JWS (JSON Web Signature): representa a assinatura do token;
- JWE (JSON Web Encryption): representa a assinatura para criptografia do token;
- JWK (JSON Web Keys): representa as chaves para a assinatura;
- JWA (JSON Web Algorithms): representa os algoritmos para assinatura do token.
Agora que você já sabe o que é, para que serve e quando usar um JWT, vamos entender mais a fundo como funciona e quais os componentes de um JWT. Vem comigo!
Componentes básicos de um JSON Web Token
Um JWT possui uma estrutura básica composta pelo header, payload e a signature. Essas três partes são separadas por pontos ( . ). Dessa forma, seria algo do tipo: header.payload.signature. Vamos entender melhor cada uma dessas partes!
Header
O Header é o cabeçalho do token, onde basicamente são informados dois dados: o alg que informa qual algoritmo é usado para criar a assinatura, e o typ que indica qual o tipo de token.
{
"alg": "HS256",
"typ": "JWT"
}Payload
É onde os dados são armazenados. Pode conter informações como o identificador do usuário, permissões, expiração do token, etc.
```json
{
"userId": "abcd-1234",
"email": "[email protected]",
"role": "editor"
}Atenção: o payload de um JWT é codificado em Base64, o que significa que qualquer pessoa consegue decodificar e ler o conteúdo. A assinatura garante apenas a integridade (ninguém alterou os dados), mas não garante confidencialidade (os dados não ficam escondidos).
Por isso, nunca coloque dados sensíveis no payload: senhas, chaves de API, números de cartão de crédito ou informações pessoais identificáveis. Segundo as melhores práticas de segurança (OWASP, RFC 8725), o JWT deve carregar apenas identificadores e claims necessários. Dados sensíveis devem permanecer armazenados de forma segura no servidor.
Signature
A assinatura do token (signature) é composta pela codificação do header e do payload combinados a uma chave secreta, utilizando o algoritmo especificado no cabeçalho.
HS256SHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload), secret_key)O resultado são três strings separadas por pontos que podem ser facilmente utilizadas em ambientes HTML e protocolos HTTP.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cIsso reforça a importância de entender como funciona um jwt token. E agora que entendemos como é “por dentro” um JWT vamos criar nosso próprio JSON Web Token!
Como criar um JWT token
Para começar, crie uma pasta chamada jwt no diretório que desejar, e em seguida, inicialize o projeto e instale a biblioteca jsonwebtoken, que é uma das mais populares para geração de JWTs:
```bash
mkdir jwt && cd jwt
npm init -y
npm install jsonwebtoken
```Crie um arquivo index.js e importe a lib:
```javascript
const jwt = require('jsonwebtoken');
``` dkjf';Agora criamos a nossa chave secreta. A ideia é que só você saiba a sua chave secreta e que ela seja difícil a fim de dificultar a ação de ataques maliciosos:
```javascript
const secretKey = 'skljaksdj9983498327453lsldkjf';
```Feito isso, vamos criar nosso token utilizando o método sign. Este método aceita como parâmetros o payload, a chave secreta e as opções (incluindo dados do header), nesta ordem.
```javascript
const nossoToken = jwt.sign(
{
userId: 'abcd-1234',
email: '[email protected]',
},
secretKey,
{
expiresIn: '15m',
subject: 'abcd-1234',
}
);
```Para este JWT, estou informando um userId e email no payload. Repare que não incluímos senha nem nenhum dado sensível. No campo de opções, estou informando um subject (que funciona como um identificador do usuário) e dizendo que nosso token expira em 15 minutos.
Tokens de curta duração são uma boa prática de segurança: se o token for interceptado, a janela de exposição é pequena. Se sua aplicação precisa manter o usuário logado por mais tempo, o recomendado é usar um refresh token separado para renovar a sessão. Por padrão, o algoritmo de codificação é o HS256.
Podemos ver nosso token gerado passando a variável nossoToken em um console.log:
```javascript
console.log(nossoToken);
```Para executar, basta rodar node index.js no terminal. A saída será algo como:
```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJhYmNkLTEyMzQiLCJlbWFpbCI6Im5vbWVAYWx1cmEuY29tLmJyIiwiaWF0IjoxNzE0NTY3ODkwLCJleHAiOjE3MTQ1Njg3OTAsInN1YiI6ImFiY2QtMTIzNCJ9.xxxxx
```Com validar e decodificar um JWT Token na prática
Para decodificar nosso token podemos utilizar um método da própria biblioteca jsonwebtoken chamado decode passando o token gerado.
```javascript
console.log(jwt.decode(nossoToken));
```A saída deste código é:
```javascript
{
userId: 'abcd-1234',
email: '[email protected]',
iat: 1714567890,
exp: 1714568790,
sub: 'abcd-1234'
}
```Onde iat e exp são as datas de criação e expiração no formato Unix timestamp, e sub é o subject que passamos no nosso código.
Importante: o método decode apenas decodifica o Base64, ele não valida a assinatura do token. Qualquer pessoa pode decodificar um JWT sem conhecer a chave secreta. Para validar de verdade que o token é autêntico e não foi alterado, use o método verify:
```javascript
try {
const tokenVerificado = jwt.verify(nossoToken, secretKey);
console.log('Token válido:', tokenVerificado);
} catch (err) {
console.error('Token inválido ou expirado:', err.message);
}
```O verify checa a assinatura e a expiração. Se algo estiver errado, ele lança um erro, por isso o try/catch.
Outra alternativa para visualizar o conteúdo de um token é acessando o site jwt.io. Neste caso, só precisamos colar o token gerado e iremos visualizar as informações decodificadas.
Agora, você deve estar se perguntando: "Agora que eu sei o que é e como funciona um JSON Web Token, como usá-lo em minhas aplicações front-end?"
Vamos descobrir!
Como funciona a autenticação JWT (jwt authentication) em aplicações web
Imagine que você é uma pessoa desenvolvedora e está criando o front-end de uma aplicação para um banco. Na página de login você pega os dados dos usuários e envia esses dados para uma API utilizando o fetch ou axios, por exemplo.
```javascript
fetch(`${baseUrl}/auth/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, password }),
})
.then((resposta) => resposta.json())
.then((dados) => {
// armazena o token recebido
})
.catch((erro) => {
// trata o erro
});
```O servidor irá pegar esses dados e, por meio de uma lógica, irá retornar um token que vai identificar aquele usuário.
Agora, toda vez que este usuário logar na plataforma, ele passará por uma autenticação e, se estiver tudo certo com os dados, será autorizado a acessar determinadas áreas da aplicação, como ver o saldo.
Geralmente essa codificação e geração de tokens é realizada pelo back-end, mas você precisará garantir que este usuário logado possa continuar acessando outras áreas da aplicação.
Para armazenar o token no front-end, existem algumas opções: sessionStorage, localStorage ou cookies httpOnly. Cada uma tem seus trade-offs. Cookies httpOnly com as flags Secure e SameSite são a opção mais segura contra ataques XSS, já que o JavaScript não consegue acessar o token.
Se sua aplicação usa SSR ou tem um BFF (Backend for Frontend), essa costuma ser a melhor escolha. Para SPAs mais simples, sessionStorage pode ser suficiente. O importante é que, enquanto o token estiver válido, a pessoa usuária permanece autenticada.
Além disso, é importante que, ao efetuar o login, o usuário seja redirecionado para uma página Home, onde poderá ver outras funcionalidades da aplicação.
Quando este usuário tentar acessar a página que mostra o seu saldo, por exemplo, você pode fazer uma requisição, passando no header um campo Authorization com o token gerado, seguindo o padrão Bearer:
```javascript
fetch(`${baseUrl}/saldo`, {
headers: {
'Authorization': `Bearer ${token}`,
},
})
.then((resposta) => resposta.json())
.then((dados) => {
// exibe o saldo
})
.catch((erro) => {
// trata o erro
});
```Isso irá fazer com que o servidor verifique se o usuário tem permissão ou não de acessar aquela página específica.
Quando a pessoa usuária fizer logout na aplicação, recomenda-se remover o token armazenado e redirecioná-la para a tela de login. Da mesma forma, se o token expirar, o ideal é direcioná-la de volta à tela de login para renovar a autenticação.
Conclusão
Quanta coisa legal não é mesmo?
Neste artigo, abordamos o que são JSON Web Tokens, para que servem, quais seus componentes e como utilizá-los em suas aplicações. Abordamos também como utilizar tokens em uma aplicação front-end para autenticação de pessoas usuárias.
Na Alura, temos a formação de Next.js que está espetacular, e também recomendo a leitura da RFC 8725 que trata mais sobre segurança com JWTs e traz um compilado excelente de boas práticas que vale a leitura.
Bons estudos e até a próxima!









