Autenticação baseada em 'Token' nas APIs REST
estou a tentar implementar uma abordagem de autenticação baseada em fichas:
cada login de sucesso cria um novo token.
Se o usuário seleciona "manter-me logado" ou o usuário está usando um dispositivo móvel, o token é persistido em um banco de dados Redis sem uma data de validade. Caso contrário, a ficha expirará em 20 minutos.
Uma vez que o Usuário é autenticado, o token é verificado a partir de cada pedido subsequente no meu banco de dados Redis.
Eu sou pergunto - me como posso identificar dispositivos. No caso de dispositivos móveis, eu posso usar um identificador de dispositivo. Mas como posso identificar um navegador?
exemplo: o utilizador regista a utilização do Chrome e selecciona "Mantenha-me ligado". Um token é gerado e persistiu com o nome do navegador em Redis. Se o usuário entrar do Firefox, salva o token e o Firefox na base de dados. Eu salvo o token em Redis enquanto token é criado em Autenticação bem sucedida. É bom persistir apenas o token e o navegador onde está a ser usada a ficha? Ou também preciso de persistir no IP?
Pergunta adicional: como evitar que atacantes roubem o token de um cookie?2 answers
Como funciona a autenticação por token
Em poucas palavras, um esquema de autenticação baseado em fichas segue estes passos:
- o cliente envia as suas credenciais (nome de utilizador e senha) para o servidor.
- o servidor autentica as credenciais e gera um token.
- o servidor guarda o item gerado anteriormente em algum armazenamento, juntamente com o identificador do utilizador e uma data de expiração.
- o servidor envia o token gerado para o cliente. Em cada pedido, o cliente envia o token para o servidor.
- o servidor, em cada pedido, extrai o token do pedido de entrada. Com o token, o servidor procura os detalhes do Usuário para realizar autenticação e autorização.
- Se o token for válido, o servidor aceita o pedido.
- Se o token for inválido, o servidor recusa o pedido.
- o servidor pode fornecer um ponto final para actualizar credito.
Como enviar credenciais para o servidor
Em aplicações de repouso, cada pedido de cliente para servidor deve conter todas as informações necessárias para serem entendidas pelo servidor. Com ele, você não está dependendo de qualquer contexto de sessão armazenado no servidor e você não quebra a restrição apátrida da arquitetura de resto definida por Roy T. Fielding em sua dissertação :
Ao aceder a recursos protegidos que requerem autenticação, cada pedido deve conter todos os dados necessários para ser autenticado/autorizado. Significa que a autenticação será realizada para cada pedido5.1.3 apátrida
[...] cada pedido de cliente a servidor deve conter todas as informações necessárias para entender o pedido, e não pode tirar proveito de qualquer contexto armazenado no servidor. O estado da sessão é, portanto, mantido inteiramente sobre o cliente. [...]
Veja esta citação do RFC 7235 em relação a considerações para novos sistemas de autenticação:
5.1.2. Considerações relativas aos novos regimes de autenticação
Existem certos aspectos do Framework de autenticação HTTP que colocar restrições sobre como os novos sistemas de autenticação podem funcionar:
- presume-se que a autenticação HTTP é apátrida: informações necessárias para autenticar um pedido deve ser fornecido no pedido, em vez de depender da memória do servidor pedidos anteriores. [...]
E os dados de autenticação (credenciais) devem pertencer ao HTTP padrão Authorization
cabeçalho. Da RFC 7235:
4.2. Autorização
O campo de cabeçalho
Authorization
permite a um agente de utilizador autenticar ele próprio com um servidor de origem -- normalmente, mas não necessariamente, depois a receber uma resposta401
(não autorizada). O seu valor consiste em: credenciais que contêm a informação de autenticação do utilizador agente para o reino do recurso a ser solicitado.Authorization = credentials
[...]
Por favor, note que o nome deste cabeçalho HTTP é infeliz porque carrega autenticação dados em vez de autorização. De qualquer forma, este é o cabeçalho padrão para enviar as credenciais .
Ao executar um autenticação baseada em fichas, as fichas são as suas credenciais . Nesta abordagem, suas credenciais (nome de usuário e senha) são trocadas por um token que é enviado em cada pedido.
Como se parece um símboloUm token de autenticação é um pedaço de dados gerados pelo servidor que identifica um usuário. Basicamente, os tokens podem ser opacos (que não revela outros detalhes para além do próprio valor, como um cadeia aleatória ) ou podem ser autónomos (como JSON Web Token):
Cadeia aleatória : um token pode ser emitido gerando uma cadeia aleatória e persistindo-a numa base de dados com uma data de expiração e com um identificador de utilizador associado a ela.
JSON Web Token (JWT): definido pelo RFC 7519, é um método padrão para representar reivindicações de forma segura entre duas partes. JWT é um token auto-contido e permite-lhe armazenar um identificador de usuário, um data de validade e o que você quiser ( mas não guarde senhas ) numa carga útil, que é um JSON codificado como Base64 . A carga útil pode ser lida pelo cliente e a integridade do token pode ser facilmente verificada verificando sua assinatura no servidor. Você não vai precisar persistir fichas JWT se você não precisa rastreá-los. Ainda que persista nos tokens, você terá a possibilidade de invalidar e revogar o acesso deles. Para manter o rasto do JWT tokens, em vez de persistir o token inteiro, você poderia persistir o token identifier (o token identifier)
jti
reivindicar) e alguns metadados (o Usuário para o qual você emitiu o token, a data de validade, etc), Se você precisar. Para encontrar grandes recursos para trabalhar com JWT, dê uma olhada em http://jwt.io.
Dica: considere sempre a remoção de fichas antigas para evitar que a sua base de dados cresça indefinidamente.
Como aceitar um token
Devias nunca aceite fichas ou fichas expiradas que não tenham sido emitidas pelo seu pedido. Se você está usando JWT, você deve verificar a assinatura token.
Por favor, note que uma vez emitido um token e entregue ao seu cliente, você não tem controle sobre o que o cliente fará com o token. sem controlo . A sério. É uma prática comum verificar oUser-Agent
campo de cabeçalho para dizer qual navegador está sendo usado para acessar a sua API. No entanto, vale a pena mencione que os cabeçalhos HTTP podem ser facilmente falsificados e você deve nunca confiar no seu cliente . Os navegadores não têm identificador único, mas pode obter um bom nível de impressões digitais se quiser.
Não sei quais são os teus requisitos de segurança, mas podes sempre tentar o seguinte no teu servidor para melhorar a segurança da tua API:
- verifique qual o navegador que o utilizador estava a usar quando o token foi emitido. Se o navegador é diferente na seguindo os pedidos, apenas recuse o token.
- obter o endereço remoto do cliente (isto é, o endereço IP do cliente) quando o token foi emitido e usar uma API de terceiros para procurar a localização do cliente. Se os seguintes pedidos forem enviados de outro país, por exemplo, recuse o token. Para procurar a localização pelo endereço IP, você pode tentar APIs livres como MaxMind GeoLite2 ou IPInfoDB . Lembre-se que atingir uma API de terceiros para cada pedido que sua API recebe não é um boa idéia e pode causar um dano grave ao desempenho. Mas você pode minimizar o impacto com um cache , armazenando o endereço remoto do cliente e a sua localização. Existem alguns motores de cache disponíveis hoje em dia. Para mencionar alguns: goiabas, Infinispan, Ehcache e Spring.
Assim que o servidor recebe o pedido do cliente, contém o agente do utilizador. Este atributo nos ajudará a identificar o cliente.
Por favor, consulte este link: Como É Que Eu detecto que navegador é usado para aceder ao meu site?