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 Node et de passport.js, les vraies questions concernent plus le flux de travail que la façon de le faire avec une technologie particulière.
Utilisons l'exemple de configuration @Keith, modifié un peu pour plus de sécurité:
- Le serveur Web à
https://example.com
sert une application cliente Javascript sur une seule page
- Le service Web RESTful sur
https://example.com/api
fournit une prise en charge du serveur à l'application client riche
- Serveur implémenté dans Node et passport.js.
- Le serveur a une base de données (de tout type) avec une table "utilisateurs".
- Le nom d'utilisateur / mot de passe et Facebook Connect sont proposés comme options d'authentification
- Le client riche transforme les requêtes REST en
https://example.com/api
- Il peut y avoir d'autres clients (applications téléphoniques, par exemple) qui utilisent le service Web à
https://example.com/api
mais ne connaissent pas le serveur Web à https://example.com
.
Notez que j'utilise HTTP sécurisé. C'est à mon avis un must pour tout service disponible à l'air libre, car des informations sensibles telles que les mots de passe et les jetons d'autorisation passent entre le client et le serveur.
Authentification par nom d'utilisateur / mot de passe
Voyons d'abord comment fonctionne l'authentification ancienne.
- L'utilisateur se connecte à
https://example.com
- Le serveur sert une application Javascript riche qui rend la page initiale. Certainshwere dans la page il y a un formulaire de connexion.
- La plupart des sections de cette application à page unique n'ont pas été remplies de données car l'utilisateur n'est pas connecté. Toutes ces sections ont un écouteur d'événement sur un événement de «connexion». Tout cela est du côté client, le serveur ne connaît pas ces événements.
- L'utilisateur entre son identifiant et son mot de passe et appuie sur le bouton d'envoi, ce qui déclenche un gestionnaire Javascript pour enregistrer le nom d'utilisateur et le mot de passe dans des variables côté client. Ensuite, ce gestionnaire déclenche l'événement "login". Encore une fois, tout cela est une action côté client, les informations d'identification n'ont pas encore été envoyées au serveur .
- Les écouteurs de l'événement "login" sont appelés. Chacun de ceux-ci doit maintenant envoyer une ou plusieurs requêtes à l'API RESTful à
https://example.com/api
pour obtenir les données spécifiques à l'utilisateur à afficher sur la page. Chaque demande qu'ils envoient au service Web comprendra le nom d'utilisateur et le mot de passe, éventuellement sous la forme d'une authentification HTTP Basic , car le service RESTful n'est pas autorisé à maintenir l'état du client d'une demande à l'autre. Le service Web étant sur HTTP sécurisé, le mot de passe est chiffré en toute sécurité pendant le transit.
- Le service Web
https://example.com/api
reçoit un tas de demandes individuelles, chacune avec des informations d'authentification. Le nom d'utilisateur et le mot de passe de chaque demande sont vérifiés par rapport à la base de données utilisateur et, s'ils sont trouvés corrects, 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, une erreur est envoyée au client sous la forme d'un code d'erreur HTTP 401.
- Au lieu de forcer les clients à envoyer un nom d'utilisateur et un mot de passe à chaque demande, vous pouvez avoir une fonction "get_access_token" dans 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 unique et expirant date qui lui est associée. Ces jetons sont stockés dans la base de données avec chaque utilisateur. Ensuite, le client envoie le jeton d'accès dans les demandes suivantes. Le jeton d'accès sera ensuite validé par rapport à la base de données au lieu du nom d'utilisateur et du mot de passe.
- Les applications clientes non navigateur comme les applications téléphoniques font la même chose que ci-dessus, elles demandent à l'utilisateur de saisir ses informations d'identification, puis de les envoyer (ou un jeton d'accès généré à partir d'elles) avec chaque demande au service Web.
Le point important à retenir de cet exemple est que les services Web RESTful nécessitent une authentification à chaque demande .
Une couche de sécurité supplémentaire dans ce scénario ajouterait une autorisation d'application cliente en plus de l'authentification utilisateur. Par exemple, si vous avez le client Web, les applications iOS et Android qui utilisent tous le service Web, vous voudrez peut-être que le serveur sache lequel des trois est le client d'une demande donnée, quel que soit l'utilisateur authentifié. Cela peut permettre à votre service Web de restreindre certaines fonctions à des clients spécifiques. Pour cela, vous pouvez utiliser des clés API et des secrets, voir cette réponse pour quelques idées à ce sujet.
Authentification Facebook
Le flux de travail ci-dessus ne fonctionne pas pour Facebook connect car la connexion via Facebook a un tiers, Facebook lui-même. La procédure de connexion nécessite que l'utilisateur soit redirigé vers le site Web de Facebook où les informations d'identification sont entrées en dehors de notre contrôle.
Voyons donc comment les choses changent:.
- L'utilisateur se connecte à
https://example.com
- Le serveur sert une application Javascript riche qui rend la page initiale. Quelque part dans la page, il y a un formulaire de connexion qui comprend un bouton "Connexion avec Facebook".
- L'utilisateur clique sur le bouton "Se connecter avec Facebook", qui est juste un lien qui redirige vers (par exemple)
https://example.com/auth/facebook
.
- L'
https://example.com/auth/facebook
itinéraire est géré par passeport.js (voir la documentation )
- Tout ce que l'utilisateur voit, c'est que la page change et qu'il se trouve maintenant sur une page hébergée sur Facebook où il doit se connecter et autoriser notre application Web. Ceci est complètement hors de notre contrôle.
- L'utilisateur se connecte à Facebook et donne la permission à notre application, donc Facebook redirige maintenant vers l'URL de rappel que nous avons configurée dans la configuration de passeport.js, qui suivant l'exemple de la documentation est
https://example.com/auth/facebook/callback
- Le gestionnaire de passeport.js pour l'
https://example.com/auth/facebook/callback
itinéraire appellera la fonction de rappel qui reçoit le jeton d'accès Facebook et certaines informations utilisateur de Facebook, y compris l'adresse e-mail de l'utilisateur.
- Avec l'e-mail, nous pouvons localiser l'utilisateur dans notre base de données et stocker le jeton d'accès Facebook avec lui.
- La dernière chose que vous faites dans le rappel Facebook est de rediriger vers l'application client riche, mais cette fois, nous devons transmettre le nom d'utilisateur et le jeton d'accès au client afin qu'il puisse les utiliser. Cela peut être fait de plusieurs manières. Par exemple, des variables Javascript peuvent être ajoutées à la page via un moteur de modèle côté serveur, ou bien un cookie peut être renvoyé avec ces informations. (merci à @RyanKimber pour avoir signalé les problèmes de sécurité liés au passage de ces données dans l'URL, comme je l'avais suggéré initialement).
- Alors maintenant, nous démarrons l'application à page unique une fois de plus, mais le client a le nom d'utilisateur et le jeton d'accès.
- L'application cliente peut déclencher immédiatement l'événement "login" et laisser les différentes parties de l'application demander les informations dont elles ont besoin au service Web.
- Toutes les demandes envoyées à
https://example.com/api
incluront le jeton d'accès Facebook pour l'authentification, ou le propre jeton d'accès de l'application généré à partir du jeton Facebook via une fonction «get_access_token» dans l'API REST.
- Les applications sans navigateur ont la tâche un peu plus difficile ici, car OAuth nécessite un navigateur Web pour la connexion. Pour vous connecter à partir d'un téléphone ou d'une application de bureau, vous devrez démarrer un navigateur pour effectuer la redirection vers Facebook, et pire encore, vous besoin d'un moyen pour le navigateur de renvoyer le jeton d'accès Facebook à l'application via un mécanisme.
J'espère que cela répond à la plupart des questions. Bien sûr, vous pouvez remplacer Facebook par Twitter, Google ou tout autre service d'authentification basé sur OAuth.
Je serais intéressé de savoir si quelqu'un a un moyen plus simple de gérer cela.
passport-facebook
. Une fois que cela fonctionne, l'étape suivante consiste à commencer à comprendre comment fonctionne Passport et comment il stocke les informations d'identification. Le connecter à Restify ( voir ici pour une version mise à jour de celui que vous mentionnez) serait l'une des dernières étapes (ou vous pourriez implémenter l'interface REST dans Express).