Começo a planejar uma API REST com node.js, express e mongodb. A API fornece dados para um site (área pública e privada) e talvez mais tarde para um aplicativo móvel. O frontend será desenvolvido com o AngularJS.
Por alguns dias, li muito sobre a proteção de APIs REST, mas não chego a uma solução final. Tanto quanto eu entendo é usar HTTPS para fornecer uma segurança básica. Mas como posso proteger a API nesses casos de uso:
Somente visitantes / usuários do site / aplicativo podem obter dados para a área pública do site / aplicativo
Somente usuários autenticados e autorizados têm permissão para obter dados para área privada (e somente dados, onde o usuário concedeu permissões)
No momento, penso em permitir apenas que usuários com uma sessão ativa usem a API. Para autorizar os usuários, usarei o passaporte e, para obter permissão, preciso implementar algo para mim. Tudo no topo do HTTPS.
Alguém pode fornecer as melhores práticas ou experiências? Existe uma falta na minha "arquitetura"?
fonte
Respostas:
Eu tive o mesmo problema que você descreve. O site que estou construindo pode ser acessado a partir de um telefone celular e do navegador, por isso preciso de uma API para permitir que os usuários se inscrevam, façam login e realizem algumas tarefas específicas. Além disso, preciso oferecer suporte à escalabilidade, o mesmo código em execução em diferentes processos / máquinas.
Como os usuários podem criar recursos (também conhecidos como ações POST / PUT), é necessário proteger sua API. Você pode usar oauth ou criar sua própria solução, mas lembre-se de que todas as soluções podem ser quebradas se a senha for realmente fácil de descobrir. A idéia básica é autenticar usuários usando o nome de usuário, senha e um token, também conhecido como apitoken. Esse apitoken pode ser gerado usando o node-uuid e a senha pode ser hash usando o pbkdf2
Então, você precisa salvar a sessão em algum lugar. Se você salvá-lo na memória em um objeto comum, se você matar o servidor e reiniciá-lo novamente, a sessão será destruída. Além disso, isso não é escalável. Se você usar haproxy para carregar o equilíbrio entre máquinas ou simplesmente usar trabalhadores, esse estado da sessão será armazenado em um único processo; portanto, se o mesmo usuário for redirecionado para outro processo / máquina, será necessário autenticar novamente. Portanto, você precisa armazenar a sessão em um local comum. Isso geralmente é feito usando redis.
Quando o usuário é autenticado (nome de usuário + senha + apitoken), gera outro token para a sessão, também conhecido como accesstoken. Novamente, com node-uuid. Envie ao usuário o accesstoken e o userid. O ID do usuário (chave) e o acesso (valor) são armazenados em redis com tempo de expiração, por exemplo, 1h.
Agora, toda vez que o usuário fizer alguma operação usando a API restante, será necessário enviar o ID do usuário e o token de acesso.
Se você permitir que os usuários se inscrevam usando a API restante, será necessário criar uma conta de administrador com uma apitoken de administrador e armazená-los no aplicativo móvel (criptografar nome de usuário + senha + apitoken) porque novos usuários não terão uma apitoken quando eles se inscrevem.
A web também usa essa API, mas você não precisa usar apitokens. Você pode usar express com uma loja redis ou usar a mesma técnica descrita acima, mas ignorando a verificação de apitoken e retornando ao usuário o ID do usuário + accesstoken em um cookie.
Se você tiver áreas privadas, compare o nome de usuário com os usuários permitidos quando eles se autenticarem. Você também pode aplicar funções aos usuários.
Resumo:
Uma alternativa sem apitoken seria usar HTTPS e enviar o nome de usuário e a senha no cabeçalho da Autorização e armazenar em cache o nome de usuário em redis.
fonte
apitoken
? é uma senha "secundária"?Eu gostaria de contribuir com este código como uma solução estrutural para a questão colocada, de acordo (espero que sim) com a resposta aceita. (Você pode personalizá-lo com muita facilidade).
Este servidor pode ser testado com curl:
fonte
Acabei de terminar um aplicativo de amostra que faz isso de uma maneira bastante básica, mas clara. Ele usa o mangusto com o mongodb para armazenar usuários e passaporte para gerenciamento de autenticação.
https://github.com/Khelldar/Angular-Express-Train-Seed
fonte
Há muitas perguntas sobre os padrões de autenticação REST aqui no SO. Estes são os mais relevantes para sua pergunta:
Basicamente, você precisa escolher entre usar chaves de API (menos seguras, pois a chave pode ser descoberta por um usuário não autorizado), uma combinação de chave e token de aplicativo (média) ou uma implementação completa do OAuth (mais segura).
fonte
Se você deseja proteger seu aplicativo, definitivamente deve começar usando HTTPS em vez de HTTP , isso garante um canal seguro de criação entre você e os usuários, que evitará cheirar os dados enviados aos usuários e ajudará a mantê-los trocados confidenciais.
Você pode usar JWTs (JSON Web Tokens) para proteger APIs RESTful ; isso tem muitos benefícios quando comparado às sessões do servidor, os benefícios são principalmente:
1- Mais escalável, pois seus servidores de API não precisarão manter sessões para cada usuário (o que pode ser um grande fardo quando você tiver muitas sessões)
2- Os JWTs são independentes e possuem as reivindicações que definem a função do usuário, por exemplo, o que ele pode acessar e emitido na data e data de validade (após o qual o JWT não será válido)
3- Mais fácil de lidar com balanceadores de carga e se você tiver vários servidores de API, não precisará compartilhar dados da sessão nem configurar o servidor para rotear a sessão para o mesmo servidor, sempre que uma solicitação com um JWT atingir qualquer servidor, ela pode ser autenticada e autorizado
4- Menos pressão no seu banco de dados, assim como você não precisará armazenar e recuperar constantemente o ID e os dados da sessão para cada solicitação
5- Os JWTs não podem ser adulterados se você usar uma chave forte para assinar o JWT, para que possa confiar nas reivindicações no JWT enviadas com a solicitação sem precisar verificar a sessão do usuário e se ele está autorizado ou não , basta verificar o JWT e pronto para saber quem e o que esse usuário pode fazer.
Muitas bibliotecas fornecem maneiras fáceis de criar e validar JWTs na maioria das linguagens de programação, por exemplo: no node.js, uma das mais populares é jsonwebtoken
Como as APIs REST geralmente têm como objetivo manter o servidor sem estado, as JWTs são mais compatíveis com esse conceito, pois cada solicitação é enviada com o token de autorização independente (JWT), sem que o servidor tenha que acompanhar a sessão do usuário em comparação com as sessões que tornam o com estado do servidor, para que ele se lembre do usuário e de sua função; no entanto, as sessões também são amplamente usadas e têm seus profissionais, que você pode procurar se quiser.
Uma coisa importante a ser observada é que você deve entregar com segurança o JWT ao cliente usando HTTPS e salvá-lo em um local seguro (por exemplo, no armazenamento local).
Você pode aprender mais sobre JWTs neste link
fonte
Se você deseja ter uma área completamente bloqueada do seu aplicativo da web que só pode ser acessada pelos administradores da sua empresa, a autorização SSL talvez seja para você. Ele garantirá que ninguém possa fazer uma conexão com a instância do servidor, a menos que tenha um certificado autorizado instalado em seu navegador. Na semana passada, escrevi um artigo sobre como configurar o servidor: Artigo
Essa é uma das configurações mais seguras que você encontrará, pois não há nome de usuário / senha envolvidos, para que ninguém possa obter acesso, a menos que um de seus usuários entregue os arquivos principais a um hacker em potencial.
fonte