web-dev-qa-db-fra.com

REST API pour le site Web qui utilise Facebook pour l'authentification

Nous avons un site Web où la seule façon de se connecter et de s'authentifier avec le site est avec Facebook (ce n'était pas mon choix). La première fois que vous vous connectez avec Facebook, un compte est automatiquement créé pour vous.

Nous voulons maintenant créer une application iPhone pour notre site et également une API publique pour que d'autres puissent utiliser notre service.

Cette question concerne la façon de s'authentifier auprès de notre site Web à partir de l'application/API et est divisée en 2 parties:

  1. Quelle est la bonne façon de gérer l'authentification REST depuis une API vers un site Web qui utilise uniquement Facebook OAuth comme méthode d'authentification?

    J'ai lu et fait beaucoup de recherches sur les méthodes d'authentification standard pour REST. Nous ne pouvons pas utiliser des méthodes telles que Basic Auth over HTTPS , car il n'y a pas d'informations d'identification pour un utilisateur en tant que tel. Quelque chose comme this semble être uniquement pour l'authentification des applications utilisant l'API.

    Actuellement, la meilleure façon que je puisse penser est de frapper un point de terminaison/autoriser sur notre API, il redirige vers Facebook OAuth, puis redirige vers le site et fournit un `` jeton '' que l'utilisateur de l'API peut utiliser pour authentifier ultérieurement demandes.

  2. Pour une application officielle que nous créons, nous n'aurions pas nécessairement besoin d'utiliser l'API publique de la même manière. Quelle serait alors la meilleure façon de parler à notre site Web et d'authentifier les utilisateurs?

Je comprends (je pense) comment authentifier des applications tierces qui utilisent notre API, en utilisant des clés API (publiques) et des clés secrètes (privées). Cependant, quand il s'agit d'authentifier l'utilisateur qui utilise l'application, je suis plutôt confus quant à la façon de procéder lorsque la seule façon d'authentifier un utilisateur est Facebook.

Je sens que je manque quelque chose de très évident, ou je ne comprends pas complètement comment les API publiques REST devraient fonctionner, donc tout conseil et aide seraient grandement appréciés.

82
Adam

MISE À JOUR: voir ci-dessous

J'ai aussi réfléchi à cette question. Ce n'est pas encore tout à fait clair pour moi, mais voici la voie à laquelle je pense. Je crée une API REST et mes utilisateurs niquement avec connexion Facebook.

Sur le CLIENT:

  1. Utilisez l'API Facebook pour vous connecter et obtenir un code OAUTH2.
  2. Échangez ce code contre un jeton d'accès.
  3. Dans chaque appel à mon API personnalisée, j'inclurai l'ID utilisateur Facebook et le jeton d'accès.

Sur l'API (pour chaque méthode qui nécessite une authentification utilisateur):

  1. Faites une demande au graphique Facebook/me à l'aide du jeton d'accès ci-dessus.
  2. Vérifiez que l'ID utilisateur Facebook renvoyé correspond à l'ID utilisateur transmis à mon API par le haut.
  3. Si le jeton d'accès a expiré, une communication supplémentaire est requise.

Je n'ai pas encore testé cela. Comment ça sonne?

--- Mise à jour: 27 juillet 2014 pour répondre à la question ---

Je n'utilise l'échange ci-dessus qu'une fois lors de la connexion. Une fois que j'ai déterminé quel utilisateur se connecte, je crée mon propre jeton d'accès, et ce jeton est utilisé à partir de ce moment. Donc, le nouveau flux ressemble à ceci ...

Sur le CLIENT:

  1. Utilisez l'API Facebook pour vous connecter et obtenir un code OAUTH2.
  2. Échangez ce code contre un jeton d'accès.
  3. Demander un jeton d'accès à l'API my, y compris le jeton Facebook comme paramètre

Sur l'API

  1. Recevez la demande de jeton d'accès.
  2. Faire une demande au graphique Facebook/me à l'aide du jeton d'accès facebook
  3. Vérifier que l'utilisateur Facebook existe et correspondre à un utilisateur de ma base de données
  4. Créer mon propre jeton d'accès, l'enregistrer et le renvoyer au client pour l'utiliser à partir de ce point
90
Chris Greenwood

Il s'agit de mon implémentation utilisant des JWT (JSON Web Tokens), essentiellement similaire à la réponse mise à jour de Chris. J'ai utilisé Facebook JS SDK et JWT.

Voici ma mise en œuvre.

  1. Client: Utilisez le SDK Facebook JS pour vous connecter et obtenir le jeton d'accès.

  2. Client: Demander JWT à mon API en appelant /verify-access-token point final.

  3. MyAPI: Reçoit le jeton d'accès, vérifiez-le en appelant /me point final de l'API Facebook.

  4. MyAPI: Si le jeton d'accès est valide, trouve l'utilisateur dans la base de données, se connecte à l'utilisateur s'il existe. Créez un JWT avec les champs obligatoires comme charge utile, définissez une expiration, signez avec la clé secrète et renvoyez-le au client.

  5. Client: Stocke le JWT dans le stockage local.

  6. Client: Envoie le jeton (le JWT de l'étape 5) avec la demande pour le prochain appel d'API.

  7. MyAPI: valider le jeton avec la clé secrète, si le jeton est valide, échanger le jeton contre un nouveau, le renvoyer au client avec le Réponse de l'API. (Aucun API externe n'appelle pour la vérification du jeton ici après) [si le jeton est invalide/expiré, le client de demande doit s'authentifier à nouveau et répéter à partir de 1]

  8. Client Remplace le jeton stocké par le nouveau et l'utilise pour le prochain appel d'API. Une fois l'expiration du jeton atteinte, le jeton expire en révoquant l'accès à l'API.

Chaque jeton est utilisé une fois.

Lire plus de réponses sur la sécurité et JWT

Quelle est la sécurité de JWT

Si vous pouvez décoder JWT, comment sont-ils sécurisés?

Jetons Web JSON (JWT) en tant que jetons d'identification et d'authentification des utilisateurs

14

J'essaie de répondre à la même question et j'ai beaucoup lu récemment ...

Je n'aurai pas "la" réponse mais les choses deviennent un peu plus claires pour moi. Avez-vous lu les commentaires dans l'article que vous avez mentionné ? Je les ai trouvés vraiment intéressants et utiles.

En conséquence, et à la lumière de l'évolution des choses depuis la rédaction du premier article, voici ce que je pense faire:

  • HTTPS partout - cela vous permet d'oublier HMAC, la signature, le nonce, ...

  • Utilisez OAuth2:

    • Lorsque les demandes d'authentification proviennent de mes propres applications/site Web, utilisez cette "astuce" (ou une variante de celle-ci) décrite dans un réponse à l'article mentionné précédemment.

    • Dans mon cas, j'ai deux types d'utilisateurs: ceux avec des identifiants de connexion/mot de passe classiques et ceux qui se sont inscrits avec Facebook Connect.
      Je fournirais donc un formulaire de connexion régulier avec un bouton "Connexion avec Facebook". Si l'utilisateur se connecte avec ses informations d'identification "classiques", je les enverrais simplement à mon point de terminaison OAuth2 avec un grant_type=password.
      S'il choisit de se connecter via Facebook, je pense que ce serait un processus en deux étapes:

      • Tout d'abord, utilisez Facebook iOS SDK pour ouvrir une session FBSession
      • Lorsque cela est fait et que l'application retrouve le contrôle, il devrait y avoir un moyen d'obtenir un identifiant Facebook pour cet utilisateur. J'enverrais cet ID seul à mon point de terminaison OAuth2 avec un octroi d'extension compris par mon serveur comme "utilisant un ID utilisateur FB".

Veuillez noter que je fais encore beaucoup de recherches sur tout cela, donc ce n'est peut-être pas une réponse parfaite ... peut-être même pas une bonne! Mais je pense que cela constituerait un bon point de départ. L'idée d'utiliser une "subvention d'extension" pour l'authentification Facebook pourrait impliquer de devoir l'enregistrer pour faire les choses correctement? Je ne suis pas tout à fait sûr.

Quoi qu'il en soit, j'espère avoir été en mesure de vous aider même un peu, et qu'au moins cela peut démarrer une discussion pour trouver la meilleure solution à ce problème :)

Mise à jour
La connexion Facebook n'est pas une solution comme indiqué dans les commentaires: n'importe qui peut envoyer un ID utilisateur arbitraire et se connecter en tant que cet utilisateur sur l'API.

Que diriez-vous de le faire comme ceci:

  • Afficher un formulaire de connexion avec un bouton "Connexion Facebook"
  • Si cette méthode de connexion est choisie, agissez un peu comme le SDK Facebook: ouvrez une page Web à partir de votre serveur d'authentification, qui lancera la connexion Facebook.
  • Une fois l'utilisateur connecté, Facebook utilisera votre URL de redirection pour confirmer; faire pointer cette URL vers un autre point de terminaison de votre serveur d'authentification (éventuellement avec un paramètre supplémentaire indiquant que l'appel provient d'une application?)
  • Lorsque le point de terminaison d'authentification est atteint, l'authentification peut identifier en toute sécurité l'utilisateur, conserver son ID utilisateur FB/session FB et renvoyer un jeton d'accès à votre application à l'aide d'un schéma d'URL personnalisé, tout comme le ferait le SDK Facebook.

Regarde mieux?

5
Olivier Lance