Login

Autenticação baseada em token facilitada

Aprenda sobre a autenticação baseada em token e como implementar o JWT com facilidade em suas aplicações.

token-based-authentication-made-easy

Autenticação baseada em token

Um token é um dado que não tem significado ou uso por conta própria, mas que, combinado com o sistema de tokenização correto, torna-se um elemento vital para proteger sua aplicação. A autenticação baseada em token funciona garantindo que cada solicitação a um servidor seja acompanhada por um token assinado que o servidor verifica quanto à autenticidade e só então responde à solicitação.

O JSON Web Token (JWT) é um padrão aberto (RFC 7519) que define um método compacto e independente para transmitir com segurança informações entre partes codificadas como um objeto JSON. O JWT ganhou uma enorme popularidade devido ao seu tamanho compacto, que permite que os tokens sejam facilmente transmitidos por meio de strings de consulta, atributos de cabeçalho e dentro do corpo de uma solicitação POST.

Você tem interesse em começar a usar os JWTs o mais rápido possível? BAIXE O EBOOK GRATUITO

Por que usar tokens?

O uso de tokens tem muitos benefícios em comparação com métodos tradicionais, como cookies.

  • Os tokens não tem monitoração de estado. O token é independente e contém todas as informações necessárias para a autenticação. Isso é ótimo para escalabilidade, pois libera seu servidor de armazenar o estado da sessão.
  • Os tokens podem ser gerados de qualquer lugar. A geração dos tokens é dissociada da verificação, permitindo lidar com a assinatura dos tokens em um servidor separado ou até mesmo por meio de uma empresa diferente, como a Auth0.
  • Controle de acesso detalhado. No payload do token, você pode especificar facilmente as funções e permissões do usuário, bem como os recursos que o usuário pode acessar.

Esses são apenas alguns dos benefícios que os JSON Web Tokens oferecem. Para saber mais, confira esta postagem do blog que se aprofunda e compara tokens a cookies para o gerenciamento de autenticação.

Anatomia de um JSON Web Token

Um JSON Web Token consiste em três partes: Cabeçalho, Payload e Assinatura. O cabeçalho e o payload são codificados em Base64 e, em seguida, concatenados por um ponto; finalmente, o resultado é assinado por algoritmo, produzindo um token na forma de header.claims.signature. O cabeçalho consiste em metadados, incluindo o tipo de token e o algoritmo de hash usado para assinar o token. O payload contém os dados das claims que o token está codificando. O resultado final se assemelha a:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJtZXNzYWdlIjoiSldUIFJ1bGVzISIsImlhdCI6MTQ1OTQ0ODExOSwiZXhwIjoxNDU5NDU0NTE5fQ.-yIVBD5b73C75osbmwwshQNRC7frWUYrqaTjTpza2y4

Os tokens são assinados para proteção contra manipulação; eles não são criptografados. O que isso significa é que um token pode ser facilmente decodificado e seu conteúdo revelado. Se navegarmos sobre o jwt.io e colarmos o token acima, poderemos ler o cabeçalho e o payload – mas sem o segredo correto, o token é inútil e vemos a mensagem “Assinatura inválida” (“Invalid Signature”). Se adicionarmos o segredo correto, neste exemplo, a string L3@RNJWT, veremos agora uma mensagem dizendo “Assinatura verificada” (“Signature Verified”).

Decodificação de um JWT com JWT.io

Em um cenário real, um cliente faz uma solicitação ao servidor e passa o token com a solicitação. O servidor tenta verificar o token e, se bem-sucedido, continua a processar a solicitação. Se o servidor não puder verificar o token, envia um 401 Unauthorized (Não autorizado) e uma mensagem dizendo que a solicitação não pôde ser processada porque a autorização não pôde ser verificada.

Práticas recomendadas do JSON Web Token

Antes de começarmos a implementar o JWT, vamos abordar algumas práticas recomendadas para garantir que a autenticação baseada em token seja implementada corretamente em sua aplicação.

  • Mantenha o web token em segredo. Mantenha-o em segurança. A chave de assinatura deve ser tratada como qualquer outra credencial e revelada apenas aos serviços que dela necessitam absolutamente.
  • Não adicione dados confidenciais ao payload. Os tokens são assinados para proteção contra manipulação e são facilmente decodificados. Adicione o número mínimo de claims ao payload para obter melhor desempenho e segurança.
  • Defina uma data de expiração para os tokens. Tecnicamente, quando um token é assinado ele é válido para sempre – a menos que a chave de assinatura seja alterada ou a expiração explicitamente definida. Isso pode acarretar problemas potenciais; portanto, tenha uma estratégia para expirar e/ou revogar tokens.
  • Adote o HTTPS. Não envie tokens por conexões não HTTPS, pois essas solicitações podem ser interceptadas e os tokens comprometidos.
  • Considere todos os seus casos de uso de autorização. Adicionar um sistema de verificação de token secundário que garanta que os tokens foram gerados em seu servidor, por exemplo, pode não ser uma prática comum, mas pode ser necessário para atender aos seus requisitos.

Para obter mais informações e práticas recomendadas, visite a publicação do blog 10 Things You Should Know About Tokens (Dez coisas que você deve saber sobre tokens).

Autenticação baseada em token facilitada

A autenticação baseada em token e o JWT têm suporte amplo. JavaScript, Python, C#, Java, PHP, Ruby, Go e outros têm bibliotecas para assinar e verificar facilmente os JSON Web Tokens. Vamos implementar uma API e ver com que rapidez podemos protegê-la com JWT.

Optamos por criar nossa API com NodeJS, pois requer menos configuração. Vamos analisar o código para nossa implementação do JWT.

// Carregue nossas dependências
var express = require('express');
var jwt = require('jsonwebtoken');

var app = express();

// Registre a rota inicial que exibe uma mensagem de boas-vindas
// Essa rota pode ser acessada sem um token
app.get('/', function(req, res){
  res.send('Welcome to our API');
})

// Registre a rota para obter um novo token
// Em um cenário realista, autenticamos as credenciais do usuário
// antes de criar um token, mas para simplificar, acessar esta rota
// gerará um novo token válido por 2 minutos
app.get('/token', function(req, res){
  var token = jwt.sign({username:'ado'}, 'supersecret',{expiresIn: 120});
  res.send(token)
})

// Registre uma rota que requer um token válido para visualizar os dados
app.get('/api', function(req, res){
  var token = req.query.token;
  jwt.verify(token, 'supersecret', function(err, decoded){
    if(!err){
      var secrets = {'accountNumber' : '938291239','pin' : '11289','account' : 'Finance'};
      res.json(secrets);
    } else {
      res.send(err);
    }
  })
})

// Inicie nossa aplicação na porta 3000
app.listen('3000');

Para testar nossa API atual, vamos executar a aplicação e navegar até localhost:3000. Veremos apenas a mensagem “Welcome to our API.” Em seguida, navegue até a rota localhost:3000/api. Uma mensagem de erro de JWT informa que não recebemos um token. Navegue até a rota localhost:3000/token e você verá um novo token gerado. Copie esse token; em seguida, navegue até localhost:3000/api?token={ADD-COPIED-TOKEN-HERE} e você verá a resposta pretendida, que são as contas financeiras da empresa.

Com apenas algumas linhas de código, conseguimos proteger nosso endpoint de API. Não abordamos o tratamento adequado da autenticação do usuário antes de gerar um token. Faremos isso com a Auth0 a seguir.

Autenticação de JWT com a Auth0

Precisamos fazer algumas pequenas modificações em nosso código para mostrar o fluxo de autenticação com a Auth0. Vamos ver as alterações abaixo:

// Carregue nossas dependências
var express = require('express');
var jwt = require('express-jwt');

var jwtCheck = jwt({
  secret: new Buffer('{YOUR-APP-SECRET}', 'base64'),
  audience: '{YOUR-APP-CLIENT-ID}'
});

var app = express();

// Em vez de buscar um token em nosso controlador
// usaremos um middleware, portanto, se o token for inválido,
// interromperemos a execução da solicitação
app.use('/api', jwtCheck);

app.get('/', function(req, res){
  res.send('Welcome to our API');
})

app.get('/api', function(req, res){
  var secrets = {'accountNumber' : '938291239','pin' : '11289','account' : 'Finance'};
  res.json(secrets);
})

app.listen('3000');

Para testar se isso funciona, vamos iniciar o servidor e navegar até localhost:3000/api. Vemos uma mensagem dizendo que não enviamos um token de autorização. Vamos até o Auth0 Playground, adicionamos nossas credenciais e obtemos um token. Adicione o seguinte código no Playground:

var domain = '{YOUR-AUTH0-DOMAIN}.auth0.com';
var clientID = '{YOUR-APP-CLIENT-ID}';

var lock = new Auth0Lock(clientID, domain);
lock.show({
  focusInput: false,
  popup: true,
}, function (err, profile, token) {
  alert(token)
});

Para garantir que possamos obter um token, precisaremos navegar para as configurações da aplicação no Auth0 Dashboard e adicionar https://auth0.github.io/playground à nossa lista de URLs de callback. Agora vamos fazer login ou criar uma conta no Auth0 Playground e ver um pop-up que mostra nosso token.

Para verificar o conteúdo do nosso token, podemos decodificá-lo em jwt.io. Para verificar o token, precisaremos do Client Secret da aplicação Auth0 e marcar a caixa codificação base64 do segredo (secret base64 encode). Fazendo isso, agora devemos ver a mensagem “Assinatura verificada” (“Signature Verified”).

Para testar se nossa API funciona com esse token, precisamos fazer uma solicitação GET para localhost:3000/api e enviar o token em um cabeçalho de autorização. A maneira mais simples de fazer isso é usar uma aplicação como o Postman, que simplifica o teste de endpoint de API. Ao fazer a chamada, adicione um cabeçalho de autorização; para o valor, adicione Bearer {TOKEN}. Quando a chamada é feita, o middleware jwtCheck examina a solicitação, garante que o cabeçalho de autorização esteja no formato correto, extrai e verifica o token, e, se confirmado, processa o restante da solicitação. Usamos apenas as configurações padrão para mostrar os recursos do JWT, mas você pode aprender muito mais por meio de docs.

Casos de uso para a autenticação baseada em token

Vimos como é fácil implementar a autenticação JWT e proteger nossa API. Para concluir, vamos examinar os casos de uso em que a autenticação baseada em token é mais adequada.

  • Aplicações de Plataforma como serviço – expor APIs RESTful que serão consumidas por uma variedade de frameworks e clientes.
  • Aplicações móveis – implementar aplicações móveis nativas ou híbridas que interagem com seus serviços.
  • Aplicações de página única (SPA) – criar aplicações modernas com frameworks como Angular e React.

Para obter recursos adicionais sobre como começar a usar JSON Web Tokens, confira estapublicação.

Inscreva-se gratuitamente

Comece a construir e proteja suas aplicações com a plataforma de identidade Auth0 hoje mesmo.

3D login box