Je développe une application Web reposante utilisant un framework Web populaire sur le backend, par exemple (Rails, sinatra, flask, express.js). Idéalement, je souhaite développer le côté client avec Backbone.js. Comment laisser uniquement mon côté client javascript interagir avec ces appels d'API? Je ne veux pas que ces appels d'API soient publics et appelés par curl
ou simplement en entrant le lien dans le navigateur.
Comme premier principe, si votre API est utilisée par votre client JS, vous devez supposer qu’elle est publique: un simple débogueur JS place un attaquant dans une position où il peut envoyer une requête identique octet par octet depuis un outil de son choix.
Cela dit, si je lis bien votre question, ce n’est pas ce que vous voulez éviter: ce que vous ne voulez vraiment pas, c’est que votre API est consommée (de manière régulière) sans que votre client JS ne soit impliqué. Voici quelques idées sur la manière de procéder sinon d'appliquer, au moins d'encourager l'utilisation de votre client:
Je suis sûr que votre API possède une sorte de champ d’authentification (par exemple, le hachage calculé sur le client). Sinon, jetez un coup d'œil à Cette SO question . Assurez-vous que vous utilisez un sel (ou même une clé API) attribué à votre client JS sur une base session (codé en dur). De cette manière, un consommateur non autorisé de votre API est contraint à beaucoup plus de travail.
Lors du chargement du client JS, souvenez-vous de certains en-têtes HTTP (l’agent utilisateur vous vient à l’esprit) et de l’adresse IP et demandez une nouvelle authentification s’ils changent, en utilisant des listes noires pour les suspects habituels. Cela force un attaquant à refaire ses devoirs.
Sur le serveur, rappelez-vous les derniers appels d’API et, avant d’en autoriser un autre, vérifiez si la logique d’entreprise permet la création du nouvel appel dès maintenant: cela empêche un attaquant de concentrer plusieurs de ses sessions en une session avec votre serveur: Dans en combinaison avec les autres mesures, cela permettra à un agresseur d'être facilement détectable.
Je n’aurais peut-être pas dit cela avec la clarté nécessaire: j’estime qu’il est impossible impossible pour un abuseur de consommer votre service, mais vous pouvez le rendre si difficile qu’il ne vaut peut-être pas la peine.
Vous devez implémenter une sorte de système d'authentification. Un bon moyen de gérer cela consiste à définir certaines variables d'en-tête attendues. Par exemple, vous pouvez avoir un appel API auth/login qui renvoie un jeton de session. Les appels ultérieurs à votre API s’attendront à ce qu’un jeton de session soit défini dans une variable d’en-tête HTTP portant un nom spécifique, tel que «votre-api-jeton».
Alternativement, de nombreux systèmes créent des jetons d'accès ou des clés attendus (tels que YouTube, Facebook ou Twitter) à l'aide d'une sorte de système de compte api. Dans ce cas, votre client devra les stocker d’une manière ou d’une autre.
Ensuite, il suffit simplement d’ajouter une vérification de la session dans votre cadre REST et de lancer une exception. Si possible, le code de statut (pour être reposant) serait une erreur 401.
Il y a un standard ouvert maintenant appelé "JSON Web Token",
voir https://jwt.io/ & https://en.wikipedia.org/wiki/JSON_Web_Token
JSON Web Token (JWT) est un standard ouvert basé sur JSON (RFC 7519) pour créer des jetons qui revendiquent un certain nombre de revendications. Par exemple, un Le serveur peut générer un jeton dont la revendication est "connectée en tant qu'administrateur" et fournir cela à un client. Le client pourrait alors utiliser ce jeton pour prouver qu'ils sont connectés en tant qu'administrateur. Les jetons sont signés par le la clé du serveur, afin que le serveur puisse vérifier que le jeton est légitime. Les jetons sont conçus pour être compacts, sécurisés pour les URL et utilisables en particulier dans le contexte de connexion unique (SSO) du navigateur Web. Les réclamations JWT peuvent être généralement utilisé pour transmettre l'identité des utilisateurs authentifiés entre un fournisseur d'identité et fournisseur de services, ou tout autre type de revendications selon les processus métier. [1] [2] Les jetons peuvent aussi être authentifié et crypté. [3] [4]
Excusez-moi @ MarkAmery et Eugene, mais c'est inexact.
Votre application js + html (client) exécutée dans le navigateur PEUT être configurée pour exclure les appels non autorisés les appels directs à l'API comme suit:
- Première étape: Configurez l'API pour exiger une authentification. Le client doit d'abord s'authentifier via le serveur (ou un autre serveur de sécurité) , par exemple, en demandant à l'utilisateur humain de fournir le mot de passe correct.
Avant l'authentification, les appels à l'API ne sont pas acceptés.
Au cours de l'authentification, un "jeton" est renvoyé.
Après l’authentification, seuls les appels d’API avec le «jeton» d’authentification seront acceptés.
Bien entendu, à ce stade, seuls les utilisateurs autorisés disposant du mot de passe peuvent accéder à l'API. Toutefois, s'ils sont des programmeurs chargés du débogage de l'application, ils peuvent y accéder directement à des fins de test.
Maintenant, pour utiliser votre API, ils doivent d'abord télécharger le client et l'exécuter dans un navigateur. L'API accepte les appels uniquement après avoir reçu le rappel, puis l'entrée de l'utilisateur dans un délai court.
Donc, vous n'avez pas à craindre qu'il s'agisse d'un utilisateur non autorisé sans informations d'identification.
(Le titre de la question, 'Comment sécuriser REST Appels d'API', et la plupart de vos propos, c'est votre principale préoccupation plutôt par qui, correct?)
Voici ce que je fais:
Sécurisez l'API avec un en-tête HTTP avec des appels tels que X-APITOKEN:
Utilisez des variables de session en PHP. Installez un système de connexion et enregistrez le jeton utilisateur dans les variables de session.
Appelez le code JS avec Ajax vers PHP et utilisez la variable de session avec curl pour appeler l'API. Ainsi, si la variable de session n'est pas définie, elle ne sera pas appelée et le code PHP contient le jeton d'accès à l'API.
Définissez une var SESSION sur le serveur lorsque le client charge pour la première fois votre index.html
(ou backbone.js
etc.)
Vérifiez cette variable côté serveur lors de chaque appel d'API.
P.S. ce n'est pas une solution "de sécurité" !!! Ceci est juste pour alléger la charge sur votre serveur afin que les gens n'abusent pas de cela ou ne "connectent pas" votre API à d'autres sites et applications.