JWT
O que é?
É um token gerado a partir de dados "pessoais", esse que pode ser trafegado entre aplicações ao se realizar requisições a APIs. As informações contidas no token são públicas e podem ser lidas por qual quer um que o possua, porém há um mecanismo de segurança que faz com que somente quem tenha a senha, possa modificá-lo.
O que faz?
De forma geral os tokens podem ser usados para diversas finalidades, afinal eles são somente uma estrutura segura para o trafego de informações, porém seu uso mais comum é para autorização de usuários em diversos serviços.
Estrutura
Header
O Header do token irá conter duas propriedades, alg
para definir o algoritmo de hash e typ
para definir o tipo de token, no nosso caso será JWT
.
{
"alg": /*algoritmo de hash*/,
"typ": "JWT",
}
{
"alg": "HS256",
"typ": "JWT",
}
Payload
O payload irá conter os dados do usuário, esses que não devem ser dados sensíveis (CPF, cartão, endereço, etc), apenas o essencial para dar ao usuário a autorização necessária para navegar e interagir com a aplicação.
{
"username": "Big John",
"name": "John Doe",
"admin": false,
"isPrime": true
}
Signature
É a assinatura utilizada para validar o token, dessa forma conseguimos verificar se o token recebido do cliente é igual ao que enviamos anteriormente, caso não sejam iguais, o token é considerado inválido.
// essa parte é a concatenação, criptografada, do Header + Payload e será gerada para nós pelo JWT.
Usando o JWT
Instalando
Antes de começarmos a implementar o JWT, precisamos instalar a biblioteca que irá gerar e validar os tokens, para isso usamos o comando:
npm i jsonwebtoken
npm i -D @types/jsonwebtoken # caso usar TypeScript será necessário instalar os pacotes a parte
Configurando
Tendo instalado e importado o JWT para nosso arquivo, iremos configurá-lo. Nas configurações podemos definir o algoritmo de hash, o período de validade, entre outas opções.
As configurações consistem em um Objeto JS com algumas chaves pré existentes. Consultar a documentação para as chaves.
const jwtConfig = {
expiresIn: '4d', // <- Faz com que o token expire depois de 4 dias
algorithm: 'HS256', // <- Indica o algoritmo de hash HS256 para criptografia
};
Criando
Após termos definido nossas configurações iremos chamar o método .sign()
para realmente criarmos nosso token, esse método irá receber os dados, o secret e as configurações como argumentos.
const jwt = require('jsonwebtoken'); // <- importação do jwt
const secret = 'meuSuperSegredo'; // Considerações logo abaixo*
const user = { email: 'gabriel@gabriel.com', username: 'Roxo' }; // <- usuário fake para demonstração
jwt.sign({ data: user }, secret, jwtConfig); // <- data é a chave padrão do JWT para passarmos os dados
*O secret deve ser armazenado em variáveis de ambiente para maior segurança da aplicação, caso o declaremos hardcoded, estaremos deixando nossa aplicação vulnerável e nossos tokens/usuários em risco.
Validando
Para validarmos um token basta chamarmos o método .verify()
, passando o token em questão e o secret utilizado como argumentos. Não se preocupe em referenciar o token criado anteriormente, pois a biblioteca do JWT faz isso para nós.
Caso o token seja inválido, ou tenha expirado, o próprio método irá nos retornar um erro, logo precisamos trabalhar essa validação dentro de um bloco try/catch
, ou algo equivalente.
/*
Assim como na criação, na validação do token precisamos importar o jwt e o secret.
E a variável secret deve ser EXATAMENTE a mesma utilizada no jwt.sign (criação) para gerar o token, caso contrário a verificação falhará.
*No caso desse exemplo seria necessário criar uma outra constante para definir o secret (NÃO RECOMENDADO)
*/
jwt.verify(token, secret);
Top comments (3)
@gabrielhsilvestre mais uma vez parabéns pelo foco, seus conteúdos me ajudam bastante, pois são diretos ao ponto, ajudando na hora de uma possível consulta para lembrar um ponto ou outro que esquecemos ou deixamos passar batido.
Fiquei com duas dúvidas, imagino que possa me ajudar a saná-las, e desde já fico agradecido.
A primeira é a seguinte, autenticação seria o processo onde o usuário envia o ‘login’ e a senha, e autorização é o processo em que envia o JWT, ou JWT pode ser considerado para o processo de autenticação também?
A segunda é porque instalar o JWT em modo de desenvolvimento como foi feito acima, tem algum motivo para isso?
Agradeço o reconhecimento e fico bem feliz que o conteúdo esteja ajudando!
Sobre as dúvidas:
1 - "Autenticação seria o processo onde o usuário envia o ‘login’ e a senha, e autorização é o processo em que envia o JWT, ou JWT pode ser considerado para o processo de autenticação também?"
Posso estar enganado, mas acho que autenticação seria o processo de validação do Token. Por exemplo: após um usuário fazer o login (outro processo) ele irá receber um Token, esse que deverá ser enviado junto de futuras requisições para que o usuário possa ser autenticado.
Enquanto a autorização seria um processo "pós login" e feito com informações do Token, por exemplo: se um usuário for administrador, seu Token poderá ter uma chave chamada
admin
recebendo o valortrue
e dentro de nossa API validamos seadmin
étrue
, se for o caso autorizamos o acesso, caso contrário bloqueamos.2 - "Porque instalar o JWT em modo de desenvolvimento como foi feito acima, tem algum motivo para isso?"
A instalação em modo de desenvolvimento é apenas para a tipagem do JWT, essa que é obrigatória para se codar com TypeScript, porque se não ele fica "perdido". Então se for codar em JavaScript, é só instalar o JWT normalmente.
Espero que tenha ficado mais claro, qualquer dúvida é só falar!
Obrigado, ficou claro sim!