155 votes

Passport.js RESTful auth

Comment gérer l'authentification (local et Facebook, par exemple) à l'aide de passport.js, au travers d'une API RESTful au lieu de passer par une interface web?

Préoccupations spécifiques sont chargés de la transmission des données à partir de rappels pour une bonne réponse (JSON) vs à l'aide d'un typique res.envoyer({ data: req.données }), la configuration initiale /de connexion d'extrémité qui redirige vers Facebook (/login ne peut pas être accédé via AJAX, parce que ce n'est pas une réponse JSON - c'est une redirection vers Facebook avec un rappel).

J'ai trouvé https://github.com/halrobertson/test-restify-passport-facebookmais je vais avoir du mal à comprendre.

En outre, comment ne passport.js stocker les informations d'identification d'authentification? Le serveur (ou est-il service?) est soutenu par MongoDB, et je m'attends à des informations d'identification (login & salé de hachage de pw) pour y être stockées, mais je ne sais pas si passport.js a ce type de capacité.

312voto

Miguel Points 15459

Il y a beaucoup de questions posées ici, et il semble que, même si les questions sont posées dans le contexte de Nœud et passport.js les vraies questions sont plus sur le flux de travail de façon à ce faire avec une technologie en particulier.

Nous allons utiliser @Keith exemple de configuration, un peu modifié pour plus de sécurité:

  • Serveur Web à l' https://example.com sert qu'à une page Javascript client app
  • Service web RESTful en https://example.com/api offre support de serveur de client riche app
  • Serveur mis en œuvre dans le Nœud et passport.js.
  • Serveur de base de données (tout type) avec une table "users".
  • Nom d'utilisateur/mot de passe et Facebook Connect sont proposés comme options d'authentification
  • Riche client rend les requêtes REST en https://example.com/api
  • Il y a peut être d'autres clients (applications de téléphone, par exemple) qui utilisent le service web à l' https://example.com/api mais ne savez pas sur le serveur web à l' https://example.com.

Note que je suis en utilisant le protocole HTTP sécurisé. C'est à mon avis un must pour n'importe quel service qui est disponible dans l'ouvert, puisque des informations sensibles comme les mots de passe et d'autorisation des jetons sont de passage entre le client et le serveur.

Nom d'utilisateur/mot de passe d'authentification

Regardons comment la plaine vieux authentification des œuvres de la première.

  • L'utilisateur se connecte à l' https://example.com
  • Le serveur sert un copieux Javascript de l'application qui rend la page initiale. Quelque part dans la page, il y a un formulaire de connexion.
  • De nombreuses sections de cette page unique application n'ont pas été remplis avec des données à l'utilisateur de ne pas être connecté. Tous ces articles ont un écouteur d'événement sur "connexion" de l'événement. Tout cela est côté client trucs, le serveur ne connaît pas de ces événements.
  • Utilisateur entre son identifiant et son mot de passe et de frappe sur le bouton soumettre, ce qui déclenche un Javascript gestionnaire d'enregistrer le nom d'utilisateur et le mot de passe dans le côté client de variables. Puis ce gestionnaire déclenche la "connexion" de l'événement. Encore une fois, c'est tout ce côté client d'action, les informations d'identification ne sont pas envoyées au serveur.
  • Les auditeurs de la "connexion" de l'événement sont invoqués. Chacun de ces maintenant besoin d'envoyer une ou plusieurs requêtes à l'API RESTful en https://example.com/api pour obtenir de l'utilisateur des données spécifiques à rendre sur la page. Chaque demande unique ils envoient le service web sera le nom d'utilisateur et le mot de passe, éventuellement sous la forme de HTTP Basic authentication, depuis le service RESTful n'est pas permis de maintenir l'état d'une demande à l'autre. Depuis le service web est sur HTTP sécurisé le mot de passe est crypté en toute sécurité pendant le transport.
  • Le service web à l' https://example.com/api reçoit un bouquet de demandes individuelles, chacune avec des informations d'authentification. Le nom d'utilisateur et mot de passe dans chaque demande est vérifiée à l'encontre de l'utilisateur de la base de données et le cas échéant de corriger la fonction demandée s'exécute et les données sont renvoyées au client au format JSON. Si le nom d'utilisateur et le mot de passe ne correspondent pas, un message d'erreur est envoyé au client sous la forme d'un code d'erreur HTTP 401.
  • Au lieu de forcer les clients à envoyer nom d'utilisateur et le mot de passe à chaque demande, vous pouvez avoir un "get_access_token" fonction de votre service RESTful qui prend le nom d'utilisateur et le mot de passe et répond avec un jeton, qui est une sorte de hachage cryptographique qui est unique et a une certaine date d'expiration associée avec elle. Ces jetons sont stockées dans la base de données avec chaque utilisateur. Ensuite, le client envoie le jeton d'accès dans les demandes ultérieures. Le jeton d'accès sera ensuite validé par rapport à la base de données au lieu du nom d'utilisateur et mot de passe.
  • Non navigateur, client des applications comme les applications de téléphone faire la même chose que ci-dessus, ils demandent à l'utilisateur d'entrer ses informations d'identification, puis de les envoyer (ou un jeton d'accès généré à partir d'eux) à chaque requête pour le service web.

Le plus important, loin de point à partir de cet exemple est que les services web RESTful exiger l'authentification avec chaque demande.

Une couche supplémentaire de sécurité dans ce scénario permettrait d'ajouter des clients d'autorisation de l'application en plus de l'authentification de l'utilisateur. Par exemple, si vous avez le client web, applications iOS et Android tous en utilisant le service web vous pouvez le serveur pour savoir lequel des trois le client d'une demande, indépendamment de l'utilisateur authentifié. Cela peut permettre à votre service web de restreindre l'utilisation de certaines fonctions spécifiques des clients. Pour cela, vous pouvez utiliser l'API de clés et secrets, voir cette réponse pour quelques idées sur le sujet.

Facebook authentification

Le flux de travail ci-dessus ne fonctionne pas pour Facebook se connecter car la connexion via Facebook a un tiers, Facebook lui-même. La procédure de connexion exige que l'utilisateur soit redirigé vers Facebook site web où les informations d'identification sont portées en dehors de notre contrôle.

Donc, nous allons voir comment les choses changent:.

  • L'utilisateur se connecte à l' https://example.com
  • Le serveur sert un copieux Javascript de l'application qui rend la page initiale. Quelque part dans la page, il y a un formulaire de connexion qui comprend une "Connexion avec Facebook" bouton.
  • L'utilisateur clique sur "Connexion avec Facebook" bouton, qui est juste un lien qui redirige vers (par exemple) https://example.com/auth/facebook.
  • L' https://example.com/auth/facebook route est gérée par passport.js (voir la documentation)
  • Tout ce que l'utilisateur voit, c'est que le changement de page, et maintenant ils sont dans une Facebook page hébergée où ils ont besoin d'un login et d'autoriser notre application web. C'est complètement hors de notre contrôle.
  • L'utilisateur se connecte à Facebook et donne la permission de notre application, Facebook maintenant la renvoie vers l'URL de callback que nous avons configuré dans le passport.js le programme d'installation, qui, suivant l'exemple de la documentation est - https://example.com/auth/facebook/callback
  • L'passport.js gestionnaire pour l' https://example.com/auth/facebook/callback route va appeler la fonction de rappel qui reçoit le Facebook jeton d'accès et des informations d'utilisateur de Facebook, y compris l'adresse électronique de l'utilisateur.
  • Avec l'e-mail, nous pouvons localiser l'utilisateur dans notre base de données et de stocker le Facebook jeton d'accès.
  • La dernière chose que vous faites dans le Facebook de rappel est la redirection de retour à l'application client riche, mais cette fois, nous avons besoin de passer le nom d'utilisateur et le jeton d'accès pour le client afin qu'il puisse les utiliser. Cela peut être fait dans un certain nombre de façons. Par exemple, les variables Javascript peut être ajouté à la page par le biais d'un serveur-côté moteur de template, ou d'autre, un cookie peut être renvoyé à cette information. (merci à @RyanKimber pour souligner les problèmes de sécurité de la transmission de ces données dans l'URL, comme je l'ai proposé initialement).
  • Alors maintenant, nous commençons le single page app une fois de plus, mais le client a le nom d'utilisateur et le jeton d'accès.
  • L'application cliente peut déclencher le "login" en cas immédiatement et laissez les différentes parties de l'application demande les informations dont ils ont besoin à partir du service web.
  • Toutes les demandes envoyées à d' https://example.com/api inclura le Facebook jeton d'accès pour l'authentification ou l'application jeton d'accès généré à partir de Facebook du jeton via un "get_access_token" fonction dans l'API REST.
  • Le navigateur des applications un peu plus difficile ici, parce que OAuth nécessite un navigateur web pour se connecter. Pour vous connecter à partir d'un téléphone ou une application de bureau, vous aurez besoin de lancer un navigateur pour faire la redirection vers Facebook, et pire encore, vous avez besoin d'un moyen pour le navigateur pour passer le Facebook jeton d'accès à l'application via un mécanisme.

J'espère que cela répond à la plupart des questions. Bien sûr, vous pouvez remplacer Facebook avec Twitter, Google, ou tout autre OAuth l'authentification basée sur les services.

Je serais curieux de savoir si quelqu'un a un moyen plus simple de faire avec.

11voto

Madhur Points 914

J'apprécie grandement @Miguel l'explication de l'ensemble des flux dans chaque cas, mais j'aimerais ajouter un peu sur le Facebook de l'Authentification de la partie.

Facebook fournit un SDK Javascript que vous pouvez utiliser pour obtenir le jeton d'accès sur le client final directement, qui est ensuite transmis au serveur et sont utilisés pour rassembler toutes les informations des utilisateurs de Facebook. Si vous n'avez pas besoin de tout re-dirige essentiellement.

En outre, vous pouvez utiliser la même API de point de fin pour les applications mobiles. Utilisez simplement le Android / iOS SDK de Facebook, obtenir le Facebook access_token sur le client et les transmettre au serveur.

Concernant les apatrides de la nature comme l'a expliqué, lors de la get_access_token est utilisé pour générer un jeton et transmis au client, ce jeton est également stockée sur le serveur. Si il est aussi bon comme un jeton de session et je crois que cela rend plus dynamique ?

Juste mes 2 cents..

3voto

myusuf Points 1018

Voici un article génial, que j’ai trouvé qui peut vous aider à authentifier avec :

  • Facebook
  • Twitter
  • Google
  • Auth local

Nœud simple authentification : Installation et Local

0voto

RLeite Points 11

Je suis d’accord avec la quasi-totalité de votre implémentation de Miguel, mais il y a une partie qui me concerne.

Si vous mettez une couche API-KEY Comment empêchez-vous autrui de copier le web API-KEY ou APP-SECRET ? Vous ne pouvez pas transmettre ces informations au client.

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