2016-01-21 1 views
12

Ich habe einige Probleme mit der Authentifizierung mit redux und reagiere Router und hoffe auf einige Erläuterungen, wie Sie mein Problem am besten lösen.Universal Auth Redux & React Router

Ich habe eine Login-Komponente, dass, wenn die folgende Aktion eingereicht entsendet:

export const loginUser = (creds) => { 
    return dispatch => { 

    dispatch(requestLogin(creds)) 

    return fetch('http://127.0.0.1:4000/api/login', { 
     ... 
    }) 
     .then(res => { 
     dispatch(receiveLogin()) 
     browserHistory.push('/admin') 
     ... 
     }) 
     ... 
    } 
} 

Die receiveLogin Aktion aktualisiert die IsAuthenticated Flagge in dem Staat wahr. Meine geschützte Route hat die folgenden onEnter hook:

export default (state) => { 
    return { 
    path: '/', 
    component: App, 
    childRoutes: [ 
     { 
     path: 'protected', 
     component: Protected, 
     ... 
     onEnter(nextState, replaceState) { 
      const loggedIn = //check state.isAuthenticated 
      if (!loggedIn) { 
      replaceState(null, 'login') 
      } 
     } 
     } 
    ] 
    } 
} 

Wie Sie sehen können, übergebe ich den Staat als Argument. Dies ermöglicht mir den Zugriff auf den Anfangszustand sowohl vom Server als auch vom Client aus. Nachdem meine Anmeldung jedoch ausgeführt wurde, verwendet der OnEnter-Hook natürlich weiterhin den Anfangszustand.

Was ich wissen möchte, ist der beste Weg, um den aktuellen Zustand zu erhalten, nachdem das isAuthenticated-Flag aktualisiert wurde und verwenden Sie das stattdessen in meinem OnEnter-Hook. Oder ist meine Herangehensweise völlig fehlerhaft und sollte ich das komplett anders machen?

Antwort

24

Ich habe festgestellt, dass die Verwendung der OnEnter-Hooks nicht der beste Ansatz in meinen Anwendungen für die Handhabung dieser Art von Auth-Logik und die Verbindung zu einem Redux-Speicher ist.

Eine der (mehreren) Fehler hier ist, dass, selbst wenn Sie einen Benutzer auf Ihre 'geschützte' Route anmelden könnten, wenn sie sich ausloggen würden, würden sie niemals zu 'Login' umgeleitet werden, weil dies nicht der Fall wäre triggert den onEnter nicht.

Ein alternativer Ansatz ist die Verwendung von Higher Order Components, siehe Dan Abramovs post über die Verwendung von ihnen über Mixins, und ich finde sie in diesem Zusammenhang auch sehr nützlich. Es gab ein paar Beispiele dafür, wie man sie benutzt, aber ich habe kürzlich eine Bibliothek redux-auth-wrapper speziell für diesen Zweck erstellt. Es ist ziemlich neu, aber ich denke, dass es nützlich sein könnte und einige Gefahren vermeidet, wenn man HOCs falsch für auth verwendet, die in infinite-loop-redirects resultieren können.

Die Idee der Verwendung eines HOC ist, dass es eine Funktion ist, die, wenn sie auf eine Komponente angewendet wird, ihre Funktionalität in irgendeiner Weise erweitert. Benutzer von redux sind wahrscheinlich mit connect vertraut, um Komponenten mit dem Abonnement für das Geschäft zu verbessern.

In diesem Fall ist die von Ihnen geschriebene Komponente nicht durch Authentifizierung/Autorisierung geschützt und wenn die HOC-Funktion angewendet wird, wird eine neue Komponente mit den angegebenen Prüfungen zurückgegeben. Wenn diese übergeben werden, wird die umschlossene Komponente zurückgegeben, andernfalls wird der Benutzer an einen Ort zum Anmelden umgeleitet (oder woanders, wenn es sich um ein Autorisierungsproblem handelt). Die HOC verwendet die Lebenszyklusmethoden componentWillMount und componentWillReceiveProps, um zu bestimmen, ob der Benutzer die gegebene Komponente sehen darf oder nicht. Dies ermöglicht die Unterstützung für das Umleiten von Komponenten bei Authentifizierungsänderungen, selbst wenn die Route dies nicht tut.

Ich würde auch Beispiele für eine ähnliche Strategie hier: https://github.com/joshgeller/react-redux-jwt-auth-example.

Und hier ist ein Beispiel, das den onEnter für Auth mit einigen Speichern Tricks verwendet, aber ich glaube, es wird nicht die Kante Fall behandeln oben beschrieben: https://github.com/CrocoDillon/universal-react-redux-boilerplate/blob/master/src/routes.jsx.

+0

Ich habe ähnliches Problem wie Andrew, aber ich verwende HOC. Mein Problem ist, dass sich der Benutzer nicht anmelden kann, weil er immer den aktuellen Status überprüft, bevor die Antwort vom Server kommt - und das bedeutet, dass sich der Benutzer nicht anmelden kann. Gibt es eine Möglichkeit, den Check im Redox-Shop zu drosseln? – Abdi

+0

@Abdi yeah Ich bin hier auf ein ähnliches Problem gestoßen: https://github.com/mjrussell/redux-auth-wrapper/issues/30. Ich denke, die Lösung besteht darin, einfach einen Flag zu Ihrem Redux-Speicher hinzuzufügen (isUserFetched) oder etwas Ähnliches, und wenn wahr - anstatt die Umleitung auszuführen, zeigen Sie eine alternative Seite im HOC anstelle der umschlossenen Komponente an. (wie eine Ladeseite). Ich möchte dies meiner Bibliothek bald hinzufügen, habe gerade noch keine Zeit – mjrussell

+0

Ich habe es tatsächlich geschafft, das Problem zu beheben, ohne auf eine in der Mitte Seite zurückgreifen. Ich habe Redux-Thunk verwendet - was die Aktion warten lässt, bis sie aufgelöst wird, dann aktualisiere ich den Status und leite dann um. Hoffe, das macht Sinn, aber wenn Sie ein ähnliches Problem haben, schauen Sie sich unbedingt [redux-thunk] an (https://github.com/gaearon/redux-thunk). Ich fand auch dieses Repo sehr hilfreich, da es das tat was ich implementieren wollte [HOC mit Authentifizierung] (https://github.com/joshgeller/react-redux-jwt-auth-example) – Abdi

Verwandte Themen