web-dev-qa-db-fra.com

Authentification avec Passport + Facebook + Express + créer-réagir-app + React-Router + proxy

TLDR: Comment lancer le processus Facebook Auth à partir d'une page de mon application React?

J'ai trouvé pas mal d'articles qui touchent à la plupart, mais pas à tous, les articles que j'ai énumérés dans le titre de cet article. Et je suis sur le point de réussir, mais il manque quelque chose. 

Mon application consiste en une interface frontale create-react-app utilisant le routeur réactif pour le routage. J'ai ce fonctionnement sur le port 51000 dans mon environnement de développement. Dans package.json, j'utilise "proxy" pour rediriger d'autres routes vers mon serveur express, fonctionnant sur le port 51001. Cela fonctionne généralement pour effectuer des demandes dans les composants React qui frappent le serveur. Par exemple:

axios.get('/api/some-stuff')

Lors de l'appel au sein de mon composant React, mon serveur Express est touché. 

Je veux m'assurer que mes routes principales sont authentifiées et j'ai choisi d'utiliser l'authentification Facebook via passport-facebook. J'ai mis cela en place, tout comme les nombreux tutoriels en ligne que j'ai vus. Par exemple, j'ai un itinéraire sur mon serveur express nommé '/ auth/facebook'. Si je vais à localhost: 51001/auth/facebook, il me redirige vers facebook pour me connecter, puis me redirige vers certains de la route que je lui ai donnée. Donc, ce flux fonctionne comme prévu.

Le problème spécifique que je rencontre est que React lance et termine avec succès l'appel de l'API qui déclenche l'authentification. J'ai essayé deux approches.

Approche 1: Appel de la route via ajax

J'ai appelé le suivant dans mon composantDidMount:

axios.get('/auth/facebook')

Cela a réussi à atteindre mon serveur express, mais immédiatement, génère l'erreur suivante dans la console du navigateur:

XMLHttpRequest ne peut pas charger _ { https://www.facebook.com/dialog/oauth?response_type=code&redirect_uri=http% … 2Flocalhost% 3A51000% 2Fauth% 2Ffacebook% 2Fcallback & client_id = XYZ. Rediriger depuis ' https://www.facebook.com/dialog/oauth?response_type=code&redirect_uri=http% … 2Flocalhost% 3A51000% 2Fauth% 2Ffacebook% 2Fcallback & client_id = XYZ' to ' (https://www.facebook.com/login.php?skip_api_login=1&api_key=XYZ } _… _ & display = page & locale = en_US & logger_id = 7f30b5a1-2ad1-dc31-f08b-70d3cfdd55fa'. a été bloqué par la politique CORS: Non 'Access-Control-Allow-Origin' l'en-tête est présent sur la ressource demandée. Origine ' http: // localhost: 51000 ' n'est donc pas autorisé à accéder.

** Approche 2: Aller à la route dans le navigateur **

L’autre chose que j’ai essayée, et que j’ai vue dans tous les tutoriels, est d’ajouter un lien vers l’une de mes pages qui permet simplement d’accéder à la route d’authentification. Par exemple:

<a href="/auth/facebook">Login with Facebook</a>

Cependant, lorsque je clique sur ceci, je me retrouve simplement à http: // localhost: 51000/auth/facebook , ou tout simplement une page vierge dans mon application React. Le proxy que j'ai n'a pas été activé, et je ne vois aucune activité sur mon serveur Express lorsque je vais sur cette route dans le navigateur, même s'il ne s'agit pas d'une route que j'ai définie dans react-router.

Donc je suis un peu coincé ici. Le fait de cliquer sur cette balise aurait-il dû déclencher le routage de cette route sur mon serveur Express? Y a-t-il un moyen de dire à react-routeur d'ignorer certaines routes afin qu'elles soient redirigées vers mon serveur express? Cela semble bien fonctionner lors d'appels AJAX, mais si je vais sur localhost: 51000/not/a/route, la requête ne sera pas redirigée vers Express. Il charge simplement une page de réaction sans contenu. 

Toute aide est appréciée. 

Merci,

-Dan

MODIFIER

Donc ça fonctionne un peu maintenant, même si je ne suis pas du tout convaincu que c'est la "bonne" façon de faire les choses. 

Dans mon application de réaction (dont le rappel est exécuté sur le port 51000), j'ai le lien suivant:

<a href="http://localhost:51001/auth/facebook">Facebook Login</a>

Notez que cela pointe directement sur mon serveur API, pas sur un itinéraire réactif. La navigation sur ce lien atteint le serveur express et redirige immédiatement vers Facebook. La connexion redirige vers mon rappel express Facebook, qui redirige lui-même vers http: // localhost: 51000/somePage }, qui est maintenant de retour sur mon application de réaction. 

Idéalement, cette balise serait dirigée vers a/api/auth/facebook, au lieu d'être codée en dur pour accéder à une autre URL/port. Je mettrai à jour ce problème si/quand je saurai comment faire en sorte que react-router le transmette au lieu de le traiter comme une page à charger.

EDIT 2

Je suis ouvert à ce que quelqu'un me dise le contraire, mais je pense que mon approche actuelle est plutôt satisfaisante. J'ai réfléchi au comportement de la production. J'aurai mon site de réaction sur www.example.com, avec mon serveur express accessible via api.example.com. Mon lien vers la connexion à Facebook sera "api.example.com/auth/facebook". Le rappel, en cas d’autorisation réussie, sera redirigé vers "www.example.com/some/route". Je pense qu'il est raisonnable de rebondir sur l'URL "api" pour effectuer la connexion. En fin de compte, il est inutile d'essayer de faire réagir-routeur pour ignorer certaines routes, car tous mes appels d'API seront dirigés vers une route explicite.Je me rends compte que je ne fournis pas une solution complète utile aux autres. Une fois que tout est mis en place, je vais inclure un lien vers mon référentiel contenant ce flux de connexion, au cas où quelqu'un le jugerait utile.

** EDIT 3 ** 

Voici des liens vers mon projet. Il ne sera pas facile de lancer l'ensemble du projet, mais il n'y a qu'une poignée de fichiers associés au flux d'authentification.

Vous pouvez voir le dépôt ici: https://github.com/dan-goyette/Portfolio _.

Le routeur du serveur Express pour cela est ici:

https://github.com/dan-goyette/Portfolio/blob/master/portfolio-server/src/Routing/auth.js

Dans l'interface utilisateur, je déclenche des appels vers le serveur express à l'aide de ce composant:

_ {{https://github.com/dan-goyette/Portfolio/blob/75ca9326e6227d0601cdfa4c0cece672bd347302/portfolio-ui/src/Components/SocialMenuButton/SocialMenuButton.js)}

Vous pouvez le voir fonctionner à https://www.dan-goyette.com/home , le bouton en haut à droite.

You can see it working at https://www.dan-goyette.com/home , the button at the top right.

18
Dan

Je rencontrais aussi ce problème. Changer la configuration du proxy de l'ARC semblait faire l'affaire:

"proxy": {
   "/api": {
      "target": "http://localhost:3001/"
   }
}

Lorsque le lien OAuth est situé à /api/auth/foo, l'application de l'ARC est à localhost:3000 et l'application express à localhost:3001.

2
romeboards

J'ai rencontré le même problème aujourd'hui et je l'ai résolu en n'utilisant pas le proxy de create-react-app, mais en configurant un proxy dans mon backend sur le create-react-app.

À la fin de mon application express, j'ai

 // all routes above

 if (env.isDevelopment()) {
   const proxy = require('express-http-proxy')
   app.use('/*', proxy('http://localhost:3000'))
 } else {
   // probably serve up build version in production
 }

Rappelez-vous simplement de désactiver le proxy dans le paquet json de votre client, sinon vous pourriez vous retrouver avec une boucle de proxy infinie ou autre.

Vous pouvez ajouter votre serveur localhost create react app à l'API Web en accédant à console.developers.google.com et en ajoutant l'hôte local create-react-app aux "Origines JavaScript autorisées" et "URI de redirection autorisées".

0
sumit

EDIT: / Ma réponse précédente n'avait rien à voir avec le problème et ne le résolvait pas. Tout dans mon cas a été causé par le registerServiceWorker dans index.js généré par CLI. Retirez-le et tout fonctionne comme il se doit.

//Remove this lines from index.js
import registerServiceWorker from './registerServiceWorker'

registerServiceWorker();
0
Braulio Miki

J'ai résolu ce problème en utilisant le champ "URL de redirection OAuth valides" dans les paramètres de développeur Facebook pour les sections de produit de connexion Facebook, par exemple, http://your-domain.loc:5000/auth/facebook

Et le bouton Facebook Auth devrait être:

<a href="http://your-domain.loc:5000/auth/facebook">Login with Facebook</a>

Vous devriez y mettre votre URL de redirection facebook. Encore une chose de mon exemple: j'utilise le port 3000 pour le serveur de nœud local et le port 5000 pour la demande d'API sur mon application.

J'utilise /etc/hosts pour utiliser mon domaine, pas localhost.

127.0.0.1   your-domain.loc

Travaille pour moi.

De plus, une discussion supplémentaire est en cours sur la ressource GitHub avec le problème - https://github.com/facebook/create-react-app/issues/3502

0