web-dev-qa-db-de.com

Authentifizierung mit Passport + Facebook + Express + Create-React-App + React-Router + Proxy

TLDR: Wie starte ich den Facebook-Authentifizierungsprozess von einer Seite in meiner React-Anwendung aus?

Ich habe etliche Posts gefunden, die die meisten, aber nicht alle Elemente betreffen, die ich im Titel dieses Posts aufgeführt habe. Und ich bin kurz davor, das zum Laufen zu bringen, aber es muss etwas fehlen, was ich vermisse. 

Meine App besteht aus einem Front-End der Create-React-App, das den Reakt-Router für das Routing verwendet. Ich habe dies auf Port 51000 in meiner Entwicklungsumgebung. In package.json verwende ich "proxy", um andere Routen an meinen Express-Server umzuleiten, der auf Port 51001 ausgeführt wird. Dies funktioniert im Allgemeinen, um Anforderungen in meinen React-Komponenten zu stellen, die den Server treffen. Zum Beispiel:

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

Beim Aufruf innerhalb meiner React-Komponente schlägt dies erfolgreich auf meinem Express-Server vor. 

Ich möchte sicherstellen, dass meine Backend-Routen authentifiziert werden, und ich habe mich für die Verwendung von Facebook-Authentifizierung über Pass-Facebook entschieden. Ich habe dies genau wie die vielen Online-Tutorials eingerichtet, die ich gesehen habe. Zum Beispiel habe ich auf meinem Express-Server eine Route mit dem Namen '/ auth/facebook'. Wenn ich zu localhost: 51001/auth/facebook gehe, leitet es mich an facebook weiter, um mich anzumelden, und leitet mich dann wieder auf die Route zurück, die ich ihm gegeben habe. Dieser Fluss funktioniert also wie erwartet.

Das spezifische Problem, das ich habe, ist das Erhalten von React, um den Aufruf der API, der auth auslöst, erfolgreich zu initiieren und abzuschließen. Ich habe zwei Ansätze ausprobiert.

Ansatz 1: Aufruf der Route über Ajax

Ich habe in meiner KomponenteDidMount Folgendes aufgerufen:

axios.get('/auth/facebook')

Dies trifft erfolgreich auf meinen Express-Server, erzeugt jedoch sofort den folgenden Fehler in der Browserkonsole:

XMLHttpRequest kann nicht geladen werden https://www.facebook.com/dialog/oauth?response_type=code&redirect_uri=http% … 2Flocalhost% 3A51000% 2Fauth% 2Ffacebook% 2Fcallback & client_id = XYZ. Weiterleitung von ' https://www.facebook.com/dialog/oauth?response_type=code&redirect_uri=http% … 2Flocalhost% 3A51000% 2Fauth% 2Ffacebook% 2Fcallback & client_id = XYZ ’an ' https://www.facebook.com/login.php?skip_api_login=1&api_key=XYZ … _ & display = page & locale = de_DE & logger_id = 7f30b5a1-2ad1-dc31-f08b-70d3cfdd55fa' wurde von der CORS-Richtlinie blockiert: Kein 'Zugriffskontroll-Zulassen-Ursprung' Der Header befindet sich auf der angeforderten Ressource. Ursprung ' http: // localhost: 51000 ' ist daher kein Zugriff erlaubt.

** Ansatz 2: Auf die Route im Browser gehen **

Die andere Sache, die ich ausprobiert habe, die ich in allen Tutorials gesehen habe, ist das Hinzufügen eines Links zu einer meiner Seiten, die einfach zur Authentifizierungsroute navigiert. Zum Beispiel:

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

Wenn ich jedoch auf dieses Symbol klicke, lande ich einfach bei http: // localhost: 51000/auth/facebook oder nur einer leeren Seite in meiner React-App. Der Proxy, den ich habe, tritt nicht ein und ich sehe keine Aktivität auf meinem Express-Server, wenn ich im Browser auf diese Route gehe, auch wenn es sich nicht um eine Route handelt, die ich im React-Router definiert habe.

Also bin ich ein bisschen hier festgefahren. Sollte durch Klicken auf dieses Tag diese Route gegen meinen Express-Server ausgelöst werden? Gibt es eine Möglichkeit, den reakt-Router anzuweisen, bestimmte Routen zu ignorieren, damit sie an meinen Express-Server weitergeleitet werden? Dies scheint gut zu funktionieren, wenn AJAX -Anrufe gemacht werden, aber wenn ich zu localhost: 51000/not/a/route gehe, wird die Anforderung nicht an Express weitergeleitet. Es wird nur eine Reaktionsseite ohne Inhalt geladen. 

Jede Hilfe wird geschätzt. 

Vielen Dank,

-Dan

EDIT

Ich habe diese Art von Arbeit jetzt, obwohl ich überhaupt nicht zuversichtlich ist, dass es die "richtige" Art ist, Dinge zu tun. 

In meiner Reakt-App (deren Rückruf auf Port 51000 ausgeführt wird) habe ich folgenden Link:

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

Beachten Sie, dass dies direkt auf meinen API-Server zeigt, nicht auf eine reagierende Route. Das Navigieren zu diesem Link trifft den Express-Server und leitet sofort zu Facebook weiter. Wenn Sie sich anmelden, wird ein Link zu meinem Express-Facebook-Callback zurückgeleitet, der sich automatisch an http: // localhost: 51000/somePage weiterleitet, das jetzt wieder zu meiner Reakt-App gehört. 

Im Idealfall würde dieses Tag zu einem/api/auth/facebook wechseln, anstatt hartcodiert zu sein, um zu einer anderen URL/einem anderen Port zu gelangen. Ich werde dieses Problem aktualisieren, wenn/wenn ich herausfinde, wie der Reakt-Router das passieren kann, anstatt ihn als eine Seite zu behandeln, die er laden muss.

EDIT 2

Ich bin offen für jemanden, der mir etwas anderes erzählt, aber ich denke, dass meine derzeitige Herangehensweise ziemlich gut ist. Ich habe überlegt, wie sich die Dinge in der Produktion verhalten werden. Ich werde meine Reaktionsseite auf www.example.com haben, wobei mein Express-Server über api.example.com erreichbar ist. Mein Link zum Facebook-Login lautet "api.example.com/auth/facebook". Der Rückruf wird unter der Voraussetzung einer erfolgreichen Authentifizierung zu "www.example.com/some/route" umgeleitet. Ich denke, es ist vernünftig, zur "api" URL zu springen, um den Login durchzuführen. Letztendlich macht es keinen Sinn, den Reakt-Router dazu zu bringen, bestimmte Routen zu ignorieren, da alle meine API-Aufrufe auf einer expliziten Route verlaufen.Mir ist klar, dass ich anderen keine vollständige hilfreiche Lösung gebe. Sobald ich alles zusammengestellt habe, füge ich einen Link zu meinem Repo hinzu, der diesen Login-Fluss enthält, für den Fall, dass es für andere hilfreich ist.

** EDIT 3 ** 

Hier sind Links zu meinem Projekt. Es ist nicht einfach, das gesamte Projekt zum Laufen zu bringen, aber es gibt nur eine Handvoll Dateien, die mit dem Auth-Fluss verknüpft sind.

Sie können das Repo hier anzeigen: https://github.com/dan-goyette/Portfolio .

Der Express-Server-Router dafür ist hier:

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

In der Benutzeroberfläche löse ich mit dieser Komponente Aufrufe an den Express-Server aus:

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

Sie können es bei _ {(https://www.dan-goyette.com/home , der Schaltfläche oben rechts, sehen.

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

18
Dan

Ich war auch auf dieses Problem gestoßen - das Ändern der CRA-Proxy-Konfiguration schien den Trick zu erfüllen:

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

Wo sich der OAuth-Link unter /api/auth/foo befindet, befindet sich die CRA-App unter localhost:3000 und die Express-App unter localhost:3001.

2
romeboards

Ich bin heute auf das gleiche Problem gestoßen und habe das Problem gelöst, indem ich nicht den Proxy von create-react-app verwendet habe, sondern stattdessen einen Proxy in meinem Backend für create-react-app eingerichtet habe.

Am Ende meiner Express-App habe ich

 // 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
 }

Denken Sie daran, den Proxy im Paket json Ihres Clients auszuschalten, da Sie sonst möglicherweise eine unendliche Proxy-Schleife oder etwas anderes erhalten.

Sie können Ihren LocalHost-Server mit Create React zur Web-API hinzufügen. Gehen Sie zu console.developers.google.com und fügen Sie den Create-React-App-Localhost den "Authorized JavaScript originins" und "Authorized Redirect URIs" hinzu.

0
sumit

EDIT: Meine vorherige Antwort hatte nichts mit dem Problem zu tun und konnte es nicht lösen. Das Ganze in meinem Fall wurde durch den registerServiceWorker in der CLI index.js verursacht. Einfach entfernen und alles funktioniert so, wie es sollte.

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

registerServiceWorker();
0
Braulio Miki

Ich habe dieses Problem mit dem Feld "Gültige OAuth-Weiterleitungs-URIs" in den Facebook-Entwicklereinstellungen für Facebook-Login-Produktabschnitte behoben, z. B. http://your-domain.loc:5000/auth/facebook

Und der Facebook-Auth-Button sollte Folgendes sein:

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

Sie sollten dort Ihre Facebook-Weiterleitungs-URL angeben. Noch etwas aus meinem Beispiel: Ich benutze 3000 Port für lokalen Knotenserver und 5000 für API-Anforderungen in meiner App.

Ich benutze /etc/hosts für meine Domain, nicht localhost.

127.0.0.1   your-domain.loc

Funktioniert bei mir.

Darüber hinaus werden in der GitHub-Ressource weitere Diskussionen mit der Ausgabe - https://github.com/facebook/create-react-app/issues/3502 geführt.

0