Je commence à planifier une API REST avec node.js, express et mongodb. L'API fournit des données pour un site Web (espace public et privé) et peut-être plus tard une application mobile. Le frontend sera développé avec AngularJS.
Pendant quelques jours, j'ai lu beaucoup de choses sur la sécurisation des API REST, mais je ne parviens pas à une solution finale. Autant que je sache, c'est d'utiliser HTTPS pour fournir une sécurité de base. Mais comment je peux protéger l'API dans ces cas d'utilisation:
Seuls les visiteurs / utilisateurs du site / de l'application sont autorisés à obtenir des données pour la zone publique du site / de l'application
Seuls les utilisateurs authentifiés et autorisés sont autorisés à obtenir des données pour un espace privé (et uniquement les données pour lesquelles l'utilisateur a accordé des autorisations)
Pour le moment, je pense à autoriser uniquement les utilisateurs ayant une session active à utiliser l'API. Pour autoriser les utilisateurs, j'utiliserai un passeport et pour obtenir la permission, je dois mettre en œuvre quelque chose pour moi. Tout en haut de HTTPS.
Quelqu'un peut-il fournir quelques bonnes pratiques ou expériences? Y a-t-il un manque dans mon «architecture»?
la source
Réponses:
J'ai eu le même problème que vous décrivez. Le site Web que je construis est accessible à partir d'un téléphone mobile et du navigateur, j'ai donc besoin d'une API pour permettre aux utilisateurs de s'inscrire, de se connecter et d'effectuer certaines tâches spécifiques. De plus, je dois prendre en charge l'évolutivité, le même code s'exécutant sur différents processus / machines.
Parce que les utilisateurs peuvent CRÉER des ressources (alias actions POST / PUT), vous devez sécuriser votre API. Vous pouvez utiliser oauth ou vous pouvez créer votre propre solution mais gardez à l'esprit que toutes les solutions peuvent être cassées si le mot de passe est vraiment facile à découvrir. L'idée de base est d'authentifier les utilisateurs en utilisant le nom d'utilisateur, le mot de passe et un jeton, alias l'apitoken. Cet apitoken peut être généré en utilisant node-uuid et le mot de passe peut être haché en utilisant pbkdf2
Ensuite, vous devez enregistrer la session quelque part. Si vous l'enregistrez en mémoire dans un objet simple, si vous tuez le serveur et le redémarrez à nouveau, la session sera détruite. De plus, ce n'est pas évolutif. Si vous utilisez haproxy pour équilibrer la charge entre les machines ou si vous utilisez simplement des travailleurs, cet état de session sera stocké dans un seul processus, donc si le même utilisateur est redirigé vers un autre processus / machine, il devra s'authentifier à nouveau. Par conséquent, vous devez stocker la session dans un endroit commun. Cela se fait généralement à l'aide de redis.
Lorsque l'utilisateur est authentifié (nom d'utilisateur + mot de passe + apitoken), générez un autre jeton pour la session, alias accesstoken. Encore une fois, avec node-uuid. Envoyez à l'utilisateur l'accesstoken et l'ID utilisateur. L'ID utilisateur (clé) et le jeton d'accès (valeur) sont stockés dans redis avec et expirent le temps, par exemple 1h.
Maintenant, chaque fois que l'utilisateur effectue une opération à l'aide de l'API de repos, il devra envoyer l'ID utilisateur et le jeton d'accès.
Si vous autorisez les utilisateurs à s'inscrire à l'aide de l'API de repos, vous devrez créer un compte administrateur avec un apitoken administrateur et les stocker dans l'application mobile (crypter nom d'utilisateur + mot de passe + apitoken) car les nouveaux utilisateurs n'auront pas d'apitoken quand ils s'inscrivent.
Le Web utilise également cette API, mais vous n'avez pas besoin d'utiliser des apitokens. Vous pouvez utiliser express avec un magasin redis ou utiliser la même technique que celle décrite ci-dessus, mais en contournant le contrôle apitoken et en renvoyant à l'utilisateur l'identifiant utilisateur + accesstoken dans un cookie.
Si vous disposez d'espaces privés, comparez le nom d'utilisateur avec les utilisateurs autorisés lors de leur authentification. Vous pouvez également appliquer des rôles aux utilisateurs.
Résumé:
Une alternative sans apitoken serait d'utiliser HTTPS et d'envoyer le nom d'utilisateur et le mot de passe dans l'en-tête d'autorisation et de mettre en cache le nom d'utilisateur dans redis.
la source
apitoken
? est-ce un mot de passe "secondaire"?Je voudrais apporter ce code comme solution structurelle à la question posée, en fonction (je l'espère) de la réponse acceptée. (Vous pouvez très facilement le personnaliser).
Ce serveur peut être testé avec curl:
la source
Je viens de terminer un exemple d'application qui le fait de manière assez basique mais claire. Il utilise mangouste avec mongodb pour stocker les utilisateurs et le passeport pour la gestion de l'authentification.
https://github.com/Khelldar/Angular-Express-Train-Seed
la source
Il y a beaucoup de questions sur les modèles d'authentification REST ici sur SO. Ce sont les plus pertinents pour votre question:
Fondamentalement, vous devez choisir entre l'utilisation de clés API (moins sécurisées car la clé peut être découverte par un utilisateur non autorisé), une combinaison de clés et de jetons d'application (moyenne) ou une implémentation complète d'OAuth (la plus sécurisée).
la source
Si vous souhaitez sécuriser votre application, vous devez certainement commencer par utiliser HTTPS au lieu de HTTP , cela garantit une création de canal sécurisé entre vous et les utilisateurs qui empêchera de renifler les données envoyées d'avant en arrière aux utilisateurs et aidera à conserver les données échangé confidentiel.
Vous pouvez utiliser des JWT (JSON Web Tokens) pour sécuriser les API RESTful , cela présente de nombreux avantages par rapport aux sessions côté serveur, les avantages sont principalement:
1- Plus évolutif, car vos serveurs API n'auront pas à maintenir de sessions pour chaque utilisateur (ce qui peut être un gros fardeau lorsque vous avez plusieurs sessions)
2- Les JWT sont autonomes et ont les revendications qui définissent le rôle d'utilisateur par exemple et ce à quoi il peut accéder et émis à la date et à la date d'expiration (après quoi le JWT ne sera pas valide)
3- Plus facile à gérer entre les équilibreurs de charge et si vous avez plusieurs serveurs API car vous n'aurez pas à partager les données de session ni à configurer le serveur pour acheminer la session vers le même serveur, chaque fois qu'une demande avec un JWT frappe n'importe quel serveur, elle peut être authentifiée & autorisé
4- Moins de pression sur votre base de données et vous n'aurez pas à stocker et récupérer en permanence l'identifiant et les données de session pour chaque demande
5- Les JWT ne peuvent pas être falsifiés si vous utilisez une clé forte pour signer le JWT, vous pouvez donc faire confiance aux revendications dans le JWT envoyé avec la demande sans avoir à vérifier la session utilisateur et s'il est autorisé ou non , vous pouvez simplement vérifier le JWT et vous êtes prêt à savoir qui et ce que cet utilisateur peut faire.
De nombreuses bibliothèques offrent des moyens simples de créer et de valider des JWT dans la plupart des langages de programmation, par exemple: dans node.js, l'un des plus populaires est jsonwebtoken
Étant donné que les API REST visent généralement à garder le serveur sans état, les JWT sont donc plus compatibles avec ce concept car chaque demande est envoyée avec un jeton d'autorisation qui est autonome (JWT) sans que le serveur doive garder une trace de la session utilisateur par rapport aux sessions qui font la serveur avec état afin qu'il se souvienne de l'utilisateur et de son rôle, cependant, les sessions sont également largement utilisées et ont leurs avantages, que vous pouvez rechercher si vous le souhaitez.
Une chose importante à noter est que vous devez livrer le JWT en toute sécurité au client en utilisant HTTPS et l'enregistrer dans un endroit sûr (par exemple dans le stockage local).
Vous pouvez en savoir plus sur les JWT à partir de ce lien
la source
Si vous souhaitez avoir une zone complètement verrouillée de votre application Web à laquelle seuls les administrateurs de votre entreprise peuvent accéder, alors l'autorisation SSL peut-être pour vous. Cela garantira que personne ne peut se connecter à l'instance de serveur à moins qu'un certificat autorisé ne soit installé dans son navigateur. La semaine dernière, j'ai écrit un article sur la configuration du serveur: Article
Il s'agit de l'une des configurations les plus sécurisées que vous trouverez car aucun nom d'utilisateur / mot de passe n'est impliqué, donc personne ne peut y accéder à moins qu'un de vos utilisateurs ne remette les fichiers clés à un pirate potentiel.
la source