Autenticação: uso de JWT vs sessão

122

Qual é a vantagem de usar JWTs em vez de sessões em situações como autenticação?

É usado como uma abordagem independente ou é usado na sessão?

Pourya8366
fonte

Respostas:

213

O JWT não tem uma vantagem sobre o uso de "sessões" por dizer. Os JWTs fornecem um meio de manter o estado da sessão no cliente em vez de fazê-lo no servidor.

O que as pessoas geralmente querem dizer quando perguntam isso é "Quais são os benefícios de usar JWTs em vez de sessões do lado do servidor "

Com as sessões do lado do servidor, você terá que armazenar o identificador da sessão em um banco de dados ou mantê-lo na memória e certificar-se de que o cliente sempre acesse o mesmo servidor. Ambos têm desvantagens. No caso do banco de dados (ou outro armazenamento centralizado), isso se torna um gargalo e algo a ser mantido - essencialmente uma consulta extra a ser feita a cada solicitação.

Com uma solução in-memory, você limita sua escala horizontal, e as sessões serão afetadas por problemas de rede (clientes em roaming entre Wifi e dados móveis, reinicialização de servidores, etc)

Mover a sessão para o cliente significa remover a dependência de uma sessão do lado do servidor, mas impõe seu próprio conjunto de desafios.

  • Armazenando o token com segurança
  • transportando-o com segurança
  • As sessões JWTs às vezes podem ser difíceis de invalidar.
  • Confiar na reivindicação do cliente.

Esses problemas são compartilhados por JWTs e outros mecanismos de sessão do lado do cliente.

O JWT em particular aborda o último deles. Pode ajudar a entender o que é um JWT:

É um pouco de informação. Para sessões de usuário, você pode incluir o nome de usuário e a hora em que o token expira. Mas pode ser qualquer coisa, até mesmo o ID da sessão ou o perfil completo do usuário. (No entanto, não faça isso) Ele tem uma assinatura segura que impede que partes mal-intencionadas gerem tokens falsos (você precisa acessar a chave privada do servidor para assiná-los e pode verificar se eles não foram modificados após serem assinados) Você envie-os com cada solicitação, assim como um cookie ou Authorizationcabeçalho seria enviado. Na verdade, eles são normalmente enviados no Authorizationcabeçalho HTTP, mas usar um cookie também é bom.

O token é assinado e, portanto, o servidor pode verificar sua origem. Assumiremos que o servidor confia em sua própria capacidade de assinar com segurança (você deve usar uma biblioteca padrão: não tente fazer isso sozinho e proteja o servidor adequadamente)

Sobre o problema de transporte seguro do token, a resposta geralmente é enviá-lo por meio de um canal criptografado, geralmente httpS.

Com relação ao armazenamento seguro do token no cliente, você precisa garantir que os bandidos não consigam acessá-lo. Isso (principalmente) significa evitar que o JS de sites ruins leiam o token e o envie de volta. Isso é atenuado usando as mesmas estratégias usadas para atenuar outros tipos de ataques XSS.

Se você precisar invalidar JWTs, definitivamente há maneiras de fazer isso. Armazenar um período por usuário apenas para usuários que solicitaram o encerramento de suas "outras sessões" é um método muito eficiente que provavelmente será bom o suficiente. Se um aplicativo precisa de invalidação por sessão, um ID de sessão pode ser mantido da mesma maneira e a tabela de "tokens eliminados" ainda pode ser mantida para ser muito menor do que a tabela de usuário completa (você só precisa reter registros mais recentes que o mais longa vida útil permitida do token.) Portanto, a capacidade de invalidar o token nega parcialmente o benefício das sessões do lado do cliente, pois você teria que manter esse estado de sessão encerrada. É mais do que provável que esta seja uma tabela muito menor do que a tabela de estado de sessão original, portanto, as pesquisas são ainda mais eficientes.

Um outro benefício de usar tokens JWT é que é razoavelmente fácil de implementar usando bibliotecas disponíveis em provavelmente todas as linguagens que você pode esperar ter. Ele também é completamente divorciado de seu esquema inicial de autenticação do usuário - se você mudar para um sistema baseado em impressão digital, não precisará fazer nenhuma alteração no esquema de gerenciamento de sessão.

Um benefício mais sutil: como o JWT pode transportar "informações" e isso pode ser acessado pelo cliente, você agora pode começar a fazer algumas coisas inteligentes. Por exemplo, lembre o usuário de que sua sessão irá expirar alguns dias antes de ele ser desconectado, dando a ele a opção de reautenticar, com base na data de expiração do token. O que você pode imaginar.

Resumindo: os JWTs respondem a algumas das perguntas e deficiências de outras técnicas de sessão.

  1. Autenticação "mais barata" porque você pode eliminar uma viagem de ida e volta do banco de dados (ou pelo menos ter uma tabela muito menor para consultar!), Que por sua vez permite escalabilidade horizontal.
  2. Reclamações do lado do cliente à prova de violação.

Embora os JWTs não respondam a outros problemas, como armazenamento ou transporte seguro, eles não apresentam novos problemas de segurança.

Existe muita negatividade em torno dos JWTs, mas se você implementar a mesma segurança que faria para outros tipos de autenticação, não terá problemas.

Uma nota final: também não é Cookies vs Tokens. Os cookies são um mecanismo para armazenar e transportar bits de informação e também podem ser usados ​​para armazenar e transportar tokens JWT.

The Tahaan
fonte
4
É importante notar que as sessões do lado do servidor também não precisam armazenar nenhuma informação no servidor. O servidor pode usar o cliente como armazenamento da mesma forma que o JWT. A verdadeira diferença está em 1) evitar as regras de segurança do navegador, passando o valor como um cabeçalho de solicitação diferente de um cabeçalho de cookie, e 2) ter um formato padronizado com JWT.
Xeoncross
1
Você diria que é seguro armazenar um jwt no armazenamento local? Se não, onde há um lugar seguro para salvá-lo para que o usuário permaneça conectado?
Jessica
1
Sim, localstorage é geralmente o lugar mais correto para armazená-lo do lado do cliente. Você precisa lidar com XSS - não sou um especialista em programação web, mas olhe Esta resposta stackoverflow.com/a/40376819/1810447 e pesquise "How To Protect Against XSS"
The Tahaan
1
Em seu comentário, você não fala sobre solução baseada em cache + token de sessão. Parece-me "melhor" do que a tabela JWT + "tokens mortos", porque com esta tabela "tokens mortos", você precisa de qualquer maneira um acesso DB, que você terá também com sessões + cache (que também é pequeno). E persistir JWT é mais doloroso de implementar do que sessões persistentes, porque você precisa brincar com um refresh_token (dois tokens para manter) ... Qualquer comentário seria muito apreciado ... especialmente se você tiver algum número para mostrar como JWT + kill_table é mais eficiente que as sessões + cache ;-)
tobiasBora
2
@TheTahaan localStorage não é recomendado para armazenar JWTs. O link que você compartilhou também menciona isso. Este blog tem uma boa explicação de por que o JWT não deve ser armazenado em localStorage.
Harke
40

A resposta curta é: Nenhum.

Uma versão mais longa é:

Implementei JWTs para gerenciamento de sessão depois de ler esta recomendação nos documentos do GraphQL :

Se você não estiver familiarizado com nenhum desses mecanismos de autenticação, recomendamos o uso de express-jwt porque é simples, sem sacrificar qualquer flexibilidade futura.

A implementação foi realmente simples, pois apenas acrescentou um pouco de complexidade. Depois de um tempo, no entanto, eu (como você) comecei a me perguntar quais eram os benefícios. Acontece que há muito poucos (ou possivelmente nenhum) para o JWT no que diz respeito ao gerenciamento de sessão, como esta postagem do blog explica em detalhes:

Pare de usar JWT para sessões

Carl von Blixen
fonte
0

Meus dois centavos, que no caminho adicionam algum contraste à famosa postagem do blog de joepie91.

Considerando que os aplicativos de hoje (e de amanhã) são (em sua maioria) nativos da nuvem
Há um benefício econômico para a Autenticação JWT sem estado , que é escalonada conforme o aplicativo é dimensionado: os
aplicativos em nuvem geram custos junto com cada respiração .
Esse custo é reduzido quando os usuários não precisam mais se autenticar "em" um armazenamento de sessão.

Processamento
Administrar uma sessão de armazenamento 24 horas por dia, 7 dias por semana, custa dinheiro.
Você não pode fugir com soluções baseadas em memória no mundo do K8S, pois os pods são efêmeros.
Sessões pegajosas não vão bem pelo mesmo motivo.

Armazenamento O
armazenamento de dados custa dinheiro. armazenar dados em um SSD custa ainda mais.
As operações relacionadas à sessão precisam ser resolvidas rapidamente, portanto, uma unidade óptica não é uma opção.

E / S
Alguns provedores de nuvem cobram dinheiro para E / S relacionadas a discos.

Largura de banda
Alguns provedores de nuvem cobram pela atividade de rede entre as instâncias do servidor.
Isso se aplica já que é quase certo que a API e o armazenamento de sessão são instâncias separadas.

Agrupando o armazenamento de sessão
O custo aumenta ainda mais todos os custos mencionados acima.

Eyal Perry
fonte
"Você não pode se safar com soluções baseadas em memória no mundo do K8S, pois os pods são efêmeros" Não tenho certeza do que você quer dizer com isso. O Redis definitivamente funciona em um ambiente K8S, e um pod de redis falhando com freqüência suficiente para afetar seus usuários parece muito improvável.
quietContest
@quietContest Eu pessoalmente prefiro não lidar com a probabilidade ao construir software. BTW, estabilidade da solução à parte, um ataque pode fazer com que o software falhe e os pods sejam reiniciados, o que resultaria na perda da sessão. Eu optaria por uma solução baseada em JWT por esse motivo.
Eyal Perry,
1
“Eu pessoalmente prefiro não lidar com a probabilidade ao construir um software”. Acho que todos nós preferiríamos isso, e é por isso que não devemos arquitetar sistemas que dependem de armazenamentos de dados na memória que nunca falham, porque a probabilidade disso parece razoavelmente alta. Quanto ao outro ponto, se você tiver um invasor capaz de desligar consistentemente sua instância do redis, a solução para isso provavelmente não precisa envolver o uso de JWTs.
quietContest
@quietContest consistentemente ou um evento único na vida são o mesmo para mim neste aspecto. ou seja, um ataque DDoS bem colocado pode fazer com que o servidor "desconecte os usuários". Isso não é bom para a reputação de confiabilidade do software. Eu acho que o redis é um exagero para o gerenciamento de sessão de qualquer maneira. Ele custa e precisa ser escalado, enquanto o armazenamento (com segurança) de um JWT em um cookie não custa.
Eyal Perry
1
@quietContest obrigado por sua contribuição, adorei a discussão!
Eyal Perry
0

Eu tive uma pergunta semelhante ao escolher entre JWT e token + cache para autenticação do usuário.

Depois de ler esses artigos, ficou claro para mim que os benefícios que o JWT promete não superam os problemas que ele traz. Portanto, token + cache (Redis / Memcached) é o caminho a percorrer para mim.

Cabeçalhos de autenticação x JWT x sessões - como escolher a técnica de autenticação correta para APIs

Técnicas de autenticação para APIs

Pare de usar jwt para sessões

h - n
fonte