web-dev-qa-db-fra.com

Autorisation et authentification à REST du client JavaScript

Je construis une PHP REST API qui sera utilisée à partir d'un client JavaScript, et j'ai des problèmes pour savoir comment implémenter le côté authentification et accès) Il y aura plusieurs applications qui utiliseront une bibliothèque JavaScript que je développerai pour parler et interagir avec mon application. Je fournirai des clés API à chacune d'entre elles, donc ce n'est pas un problème.

Là où je commence à être confus, c'est comment faire en sorte que les utilisateurs de ces sites s'authentifient auprès de mon application. Il semble que ce soit une mauvaise idée que ce site externe stocke les informations de mon compte d'utilisateur et de mon mot de passe; donc, je suppose que je devrais avoir ma bibliothèque JavaScript inclure un widget de connexion qui demande les informations de compte de l'utilisateur pour mon application.

Si l'authentification y réussit, puisque je travaille avec une API REST, je devrai stocker le jeton récupéré dans un cookie côté client ou quelque chose pour que l'utilisateur n'ait pas besoin de me reconnecter à mon application sur chaque page du site externe. Cependant, que se passe-t-il si l'utilisateur se déconnecte du site externe, puis qu'un autre utilisateur se connecte à partir du même navigateur? En ce qui concerne ma bibliothèque JavaScript, l'ancien utilisateur serait toujours connecté à mon application, car le cookie/jeton n'aurait pas encore expiré - comment puis-je effacer mon cookie à la fin de la session de l'utilisateur précédent? Ou, suis-je complètement hors du bon chemin ici?

Donc, je pense que le processus serait quelque chose comme:

var token; // Some hashed string containing an expiration date and user id
var apiKey = '123abc';

// Read the cookie and check if it already contains the token
token = readCookie('token');
if (token == '') {
    // get username and password from user through some Prompt

    var request_data = {apiKey: apiKey, user: username, pass: password};
    $.post('https://service.com/api/user/login', request_data, function(data) {
        token = data;
        document.cookie = "token=" + token;
    });
}

...

var get_data = {apiKey: apiKey, token: token};
$.get('http://service.com/api/<object>', get_data, function(data) {
    // Do something with data
});

Désolé, il y a plusieurs questions enterrées ici. Je suppose que le principal est que si je stocke le jeton dans un cookie, comment puis-je m'assurer qu'il est effacé lorsque l'utilisateur se déconnecte de l'application externe? Ou, si je ne dois pas le stocker dans un cookie, comment tenir le client au courant de l'état de l'utilisateur?

22
lightstrike

Je vous suggère de lire ceci très bon article de blog sur la sécurisation d'une API RESTful.

(Au cas où ce lien ne fonctionnerait pas - il est déjà mort une fois et doit être récupéré sur archive.org - j'ai trouvé ce qu'il semble être un PDF rendu de cette page accessible ici) : https://www.ida.liu.se/~TDDD97/labs/hmacarticle.pdf .)

Remarque: ma réponse est hors sujet car la solution fournie dans le blog ci-dessus n'est pas sécurisée à partir d'un client Javascript. En fait, il explique principalement comment sécuriser une REST API côté serveur.

41
Epoc

"Là où je commence à être confus, c'est comment faire en sorte que les utilisateurs de ces sites s'authentifient auprès de mon application. Cela semble être une mauvaise idée que ce site externe stocke les informations de mon compte et de mon mot de passe;" -

Avec REST, la meilleure façon de gérer cela est d'utiliser vos clients (pages Web, applications mobiles), qu'ils soient contrôlés par votre domaine ou qu'ils passent par les informations d'identification de l'utilisateur saisies par l'utilisateur (dans le page de connexion). Vous disposez d'une API de connexion/déconnexion qui se charge de l'authentification.

Lorsque l'API de connexion s'authentifie, elle retourne un jeton (hachage unidirectionnel peut-être des préférences de l'utilisateur), qui peut être stocké dans un cookie chiffré côté client. De cette façon, vos clients ne gèrent jamais directement les informations d'identification de l'utilisateur. Le jeton est configuré pour expirer à tout moment.

Pour tous les appels suivants à l'API REST, vos clients soumettront ce jeton avec la demande à l'API (qui est différente de l'API de connexion/déconnexion). L'API peut peut-être vérifier un cache local ( sur le REST serveur) pour voir s'il s'agit d'un jeton valide. S'il est trouvé, il honore la demande. Sinon, génère une erreur.

Si l'utilisateur se déconnecte avant l'expiration du jeton, l'API de connexion/déconnexion supprimera ce jeton du cache local et vos clients devront supprimer la session/le cookie.

De cette façon, vos informations d'identification ne sont jamais transmises du côté client.

Et bien sûr, la sécurité des données en mouvement devrait également être assurée par SSL et HTTP Digest.

8
Kingz

S'il s'agit d'une API privée (vous avez une table d'utilisateurs) allant d'un domaine à l'autre d'un autre nom d'hôte à votre propre nom d'hôte, je suis d'accord avec ce qui précède et je suggère une connexion/déconnexion (SSL) simple à laquelle vous pouvez donner à l'utilisateur (ou emporter) des cookies de votre domaine.

S'il s'agit d'une API publique (n'importe qui peut obtenir une clé API pour, par exemple), je suggère d'utiliser la méthode dans le billet de blog de la réponse ci-dessus.

Pour le client JavaScript, essayez https://github.com/jpillora/jquery.rest s'il manque quelque chose, soumettez une demande de fonctionnalité ou contribuez si vous le souhaitez :)

1
jpillora