68 votes

Sécuriser l'API REST de mon application Node.js ?

J'aurais besoin d'aide pour mon API REST. J'écris une application Node.js qui utilise Express, MongoDB et Backbone.js du côté client. J'ai passé les deux derniers jours à essayer de résoudre tout cela et je n'ai pas eu beaucoup de chance. J'ai déjà vérifié :

Je veux que mon backend et mon frontend soient aussi séparés que possible. J'ai donc pensé qu'il serait bon d'utiliser une API REST soigneusement conçue. Je me suis dit que si je parvenais un jour à développer une application iPhone (ou autre), celle-ci pourrait utiliser l'API pour accéder aux données.

MAIS, je veux que ce soit sécurisé. Un utilisateur s'est connecté à mon application Web et je veux m'assurer que mon API est sécurisée. Je me suis renseigné sur OAuth, OAuth 2.0, OpenID, Hmac, hashs, etc... Je veux éviter d'utiliser une connexion externe (Facebook/Twitter/etc). Je veux que l'enregistrement et la connexion se fassent sur mon application/serveur.

...mais je suis toujours confus ici. Peut-être qu'il est tard dans la nuit ou que mon cerveau est juste grillé, mais j'aurais vraiment besoin de quelques conseils sur ce qu'il faut faire ici. Quelles sont les étapes à suivre pour créer une API sécurisée ?

Toute aide, toute information, tout exemple, toute étape ou tout autre élément serait le bienvenu. Aidez-nous !

0 votes

Qu'avez-vous fini par faire ?

39voto

ghickman Points 1989

Par ordre croissant de sécurité / complexité :

Authentification HTTP de base

De nombreuses bibliothèques d'API vous permettent d'intégrer cette fonction (Piston dans Django, par exemple) ou vous pouvez laisser votre serveur Web s'en charger. Nginx et Apache peuvent tous deux utiliser des directives de serveur pour sécuriser un site avec un simple mot de passe codé en b64. Ce n'est pas la chose la plus sûre au monde, mais c'est au moins un nom d'utilisateur et un mot de passe !

Si vous utilisez Nginx, vous pouvez ajouter une section à la configuration de votre hôte comme suit :

auth_basic "Restricted";
auth_basic_user_file /path/to/htpasswd;

(Mettez-le dans votre location / bloc)

Docs : http://wiki.nginx.org/HttpAuthBasicModule

Vous devrez obtenir le script python pour générer ce mot de passe et mettre la sortie dans un fichier : http://trac.edgewall.org/browser/trunk/contrib/htpasswd.py?format=txt

L'emplacement du fichier n'a pas trop d'importance, tant que Nginx peut y accéder.

HTTPS

Sécurisez la connexion entre votre serveur et l'application. Il s'agit de la mesure la plus élémentaire, qui permet d'éviter les attaques de type "man in the middle".

Vous pouvez le faire avec Nginx, dont la documentation est très complète : http://wiki.nginx.org/HttpSslModule

Un certificat auto-signé pour cela serait parfait (et gratuit !).

Clés API

Ces documents peuvent être présentés dans le format de votre choix, mais ils vous permettent de révoquer l'accès en cas de besoin. Ce n'est peut-être pas la solution idéale pour vous si vous développez les deux extrémités de la connexion. Ils sont généralement utilisés lorsque des tiers utilisent l'API, par exemple Github.

OAuth

OAuth 2.0 est la solution à privilégier ici. Bien que je ne connaisse pas les mécanismes sous-jacents de la spécification, c'est la norme de facto pour la plupart des authentifications maintenant (Twitter, Facebook, Google, etc.) et il y a une tonne de bibliothèques et de documents pour vous aider à les mettre en œuvre. Ceci étant dit, elle est généralement utilisée pour authentifier un utilisateur en demandant l'authentification à un service tiers.

Étant donné que vous effectuez le développement des deux côtés, il serait probablement suffisant de placer votre API derrière Basic HTTP Auth et de la servir sur HTTPS, surtout si vous ne voulez pas perdre de temps à vous embêter avec OAuth.

0 votes

Excellente réponse. Je vois que OAuth semble être la norme. Mais il semble qu'il y ait OAuth 1.0 à 2 pattes, OAuth 1 à 3 pattes et ensuite OAuth 2... Je devrais donc m'intéresser à OAuth 2 ? ...Je pensais à HTTPS/SSL, mais je ne suis pas sûr de savoir comment quelque chose comme une application iPhone pourrait transmettre par ce biais (est-ce même possible) ? ...une autre question avec OAuth, puis-je être à la fois fournisseur et consommateur, ou dois-je - comme vous le dites - utiliser un tiers pour m'authentifier ? Dans cette situation, l'utilisation d'un tiers ne serait pas trop préférable, ce n'est pas vraiment ce genre d'application. Merci pour cette réponse détaillée !

0 votes

OAuth 2 est la version actualisée d'OAuth. Je crois que la version 1.0 est maintenant considérée comme "mauvaise". L'iPhone fonctionnera certainement sur HTTPS (Github dans Safari mobile !).

0 votes

Vous peut Il peut s'agir des deux, mais OAuth est généralement utilisé pour s'authentifier auprès d'un tiers. Comme @mjtamlyn l'a souligné ci-dessous, utiliser votre système d'authentification actuel est certainement une possibilité. J'ai mis à jour ma réponse avec quelques étapes pour certaines des parties.

29voto

mjtamlyn Points 824

Voici une autre façon d'y penser :

Supposons un instant que vous n'utilisez pas d'API. Votre utilisateur se connecte à l'application en fournissant des informations d'identification, et vous lui donnez un cookie ou un jeton similaire que vous utilisez pour identifier la connexion de l'utilisateur. L'utilisateur demande ensuite une page contenant des informations à accès restreint (ou la création/modification/suppression de celles-ci), vous vérifiez donc ce jeton pour vous assurer que l'utilisateur est autorisé à consulter ces informations.

Il me semble que la seule chose que vous changez ici est la façon dont l'information est délivrée. Au lieu de livrer l'information sous forme de HTML rendu, vous retournez l'information sous forme de JSON et la rendez du côté client. Vos requêtes AJAX vers le serveur porteront le même jeton de connexion qu'auparavant, je suggère donc de vérifier ce jeton et de restreindre les informations à "ce que l'utilisateur est autorisé à savoir" de la même manière.

Votre API est désormais aussi sûre que votre connexion. Si quelqu'un connaissait le jeton nécessaire pour accéder à l'API, il serait également connecté au site et aurait de toute façon accès à toutes les informations. Si vous avez déjà implémenté la connexion, vous n'avez pas besoin de faire plus de travail.

L'intérêt de systèmes tels qu'OAuth est de fournir cette méthode de "connexion", généralement à partir d'une application tierce et en tant que développeur. Ce serait potentiellement une bonne solution pour une application iPhone ou similaire, mais c'est dans le futur. Il n'y a rien de mal à ce que l'API accepte plus d'une méthode d'authentification !

0 votes

Alors, est-ce que je réfléchis trop, je suppose ? J'ai déjà une authentification "normale" en cours... L'utilisateur se connecte, un cookie est créé pour la session et le site vérifie si l'utilisateur est connecté pour les différentes parties "sécurisées". Donc, en substance, c'est tout !? ...Je réfléchis trop au problème et j'essaie de traiter avec OAuth, etc., mais en réalité, il s'agit toujours de l'authentification de base... Maintenant, si c'est ce que c'est, alors c'est très bien ! Je suppose que, le cas échéant, j'ai besoin d'obtenir SSL sur mon serveur, mais à part cela, je peux simplement utiliser ma procédure normale d'authentification ?

0 votes

Oui, c'est en gros ce que je voulais dire. SSL est une bonne idée parce que JSON est un format facilement lisible pour les données, mais vous pouvez aussi le faire pour l'ensemble du site tant que vous y êtes.

1 votes

Il se peut que quelque chose m'échappe ici, mais cela ne viole-t-il pas en quelque sorte la règle fondamentale des API ? C'est-à-dire : pas d'état côté serveur ? Si le serveur a besoin de garder la trace des jetons, cela signifie qu'il doit conserver un état, ce qui devrait être un peu un non-non :-)

8voto

andyzinsser Points 798

Les réponses fournies jusqu'à présent sont très explicites, mais ne donnent pas d'étapes concrètes. Je suis tombé sur cet article de blog qui explique en détail comment créer et gérer les jetons de manière sécurisée avec Node + Passport.

http://aleksandrov.ws/2013/09/12/restful-api-with-nodejs-plus-mongodb/

0voto

Ahmed Elkoussy Points 885

Conseils valables pour sécuriser toute application web

Si vous voulez sécuriser votre candidature, alors vous devez absolument commencer par utiliser HTTPS au lieu de HTTP. Cela garantit la création d'un canal sécurisé entre vous et les utilisateurs, ce qui empêchera le reniflage des données envoyées et reçues par les utilisateurs et contribuera à préserver la confidentialité des données échangées.

Vous pouvez utiliser les JWT (JSON Web Tokens) pour sécuriser les API RESTful. Cette méthode présente de nombreux avantages par rapport aux sessions côté serveur :

1- Plus évolutif, car vos serveurs API n'auront pas à maintenir des sessions pour chaque utilisateur (ce qui peut être une lourde charge lorsque vous avez de nombreuses sessions).

2- Les JWT sont autonomes et comportent des revendications qui définissent le rôle de l'utilisateur, par exemple, et ce à quoi il peut accéder. Ils sont émis à une date et à une date d'expiration (après quoi le JWT ne sera plus valide).

3- Plus facile à gérer à travers 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 qu'il achemine la session vers le même serveur, chaque fois qu'une demande avec un JWT atteint un serveur, elle peut être authentifiée et autorisée.

4- Moins de pression sur votre base de données, car vous ne devrez pas constamment stocker et récupérer l'identifiant de session et les données pour chaque demande.

5- Les JWTs ne peuvent pas être altérés si vous utilisez une clé forte pour signer le JWT, donc vous pouvez faire confiance aux déclarations dans le JWT qui est envoyé avec la demande sans avoir à vérifier la session de l'utilisateur et s'il est autorisé ou non, vous pouvez juste vérifier le JWT et alors vous êtes prêt à savoir qui et ce que cet utilisateur peut faire.

Bibliothèques spécifiques à Node.js pour implémenter JWTs :

De nombreuses bibliothèques offrent des moyens simples de créer et de valider des JWT, par exemple : dans node.js, l'une des plus populaires est la suivante jsonwebtoken Pour valider les JWTs, vous pouvez également utiliser la même bibliothèque ou utiliser express-jwt ou koa-jwt (si vous utilisez express/koa)

Étant donné que les API REST visent généralement à maintenir le serveur sans état, les JWT sont plus compatibles avec ce concept car chaque demande est envoyée avec un jeton d'autorisation qui est autonome. (JWT) sans que le serveur n'ait à garder la trace de la session de l'utilisateur, contrairement aux sessions, qui font que le serveur se souvient de l'utilisateur et de son rôle. Cependant, les sessions sont aussi largement utilisées et ont leurs avantages, que vous pouvez rechercher si vous le souhaitez.

Il est important de noter que vous devez transmettre le JWT au client de manière sécurisée en utilisant le protocole HTTPS et le sauvegarder dans un endroit sûr (par exemple dans un stockage local).

Vous pouvez en savoir plus sur les JWT à partir de ce lien

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X