2016-01-21 10 views
12

Ho qualche problema con l'autenticazione con redux e react router e spero di avere qualche chiarimento su come risolvere al meglio il mio problema.Universal Auth Redux & React Router

Ho un componente di accesso che, se presentate invia la seguente azione:

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') 
     ... 
     }) 
     ... 
    } 
} 

L'azione receiveLogin aggiorna la bandiera isAuthenticated nello stato true. Il mio percorso protetto ha il seguente hook onEnter:

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') 
      } 
     } 
     } 
    ] 
    } 
} 

Come puoi vedere, sto passando lo stato come argomento. Questo mi dà accesso allo stato iniziale dal server e dal client. Tuttavia, dopo che si è verificata l'azione di accesso, ovviamente il gancio onEnter continuerà a utilizzare lo stato iniziale.

Quello che voglio sapere è il modo migliore per ottenere lo stato corrente dopo che il flag isAuthenticated è stato aggiornato e usarlo invece nel mio hook onEnter. Oppure, il mio approccio è totalmente errato e dovrei farlo in un modo completamente diverso?

risposta

24

Ho scoperto che l'utilizzo degli hook onEnter non è l'approccio migliore nelle mie applicazioni per la gestione di questo tipo di autenticazione logica e la connessione a un negozio redux.

Una delle (molte) insidie ​​qui è che anche se si potesse accedere a un utente alla propria rotta 'protetta', se dovessero disconnettersi mentre si è in 'protetti' non verrebbero mai reindirizzati a 'login' perché non sarebbe Attivare onEnter.

Un approccio alternativo consiste nell'utilizzare componenti di ordine superiore, vedere post di Dan Abramov sul loro utilizzo con i mixin e li trovo davvero utili anche in questo contesto. Ci sono stati alcuni repository/esempi di repository di come usarli, ma recentemente ho creato una libreria redux-auth-wrapper specificatamente per questo scopo. È piuttosto nuovo, ma penso che potrebbe essere utile ed evita alcuni pericoli quando si utilizza HOC in modo errato per auth che può risultare in infinite-loop-redirects.

L'idea di utilizzare un HOC è che è una funzione che quando viene applicata a un componente estende la sua funzionalità in qualche modo. Gli utenti di Redux hanno probabilmente familiarità con connect per migliorare i componenti con la sottoscrizione per il negozio.

In questo caso, la componente scritta non è protetta da autenticazione/autorizzazione e quando viene applicata la funzione HOC, viene restituito un nuovo componente con i controlli specificati. Se questi passano, viene restituito il componente spostato, altrimenti l'utente viene reindirizzato a un luogo di accesso (o da qualche altra parte se si tratta di un problema di autorizzazione). L'HOC fa uso dei metodi del ciclo di vita componentWillMount e componentWillReceiveProps per determinare se l'utente è autorizzato a vedere o meno il componente specificato. Ciò consente il supporto per il reindirizzamento di componenti su modifiche di autenticazione anche se il percorso non lo fa.

Vorrei anche controllare esempi di una strategia simile qui: https://github.com/joshgeller/react-redux-jwt-auth-example.

Ed ecco un esempio che utilizza onEnter per l'autenticazione con alcuni trucchi del negozio, ma credo che non gestirà il caso limite descritto sopra: https://github.com/CrocoDillon/universal-react-redux-boilerplate/blob/master/src/routes.jsx.

+0

Ho un problema simile a quello di Andrew, ma sto usando HOC. Il mio problema è che l'utente non può accedere, perché controlla sempre lo stato corrente prima che la risposta ritorni dal server - e questo significa che l'utente non può accedere. C'è un modo per limitare il controllo nel negozio redux? – Abdi

+0

@Abdi si ho trovato un problema simile qui: https://github.com/mjrussell/redux-auth-wrapper/issues/30. Penso che la soluzione sia semplicemente aggiungere un flag al tuo redux store (isUserFetched) o qualcosa di simile e se è vero - invece di eseguire il reindirizzamento, mostra una pagina alternativa nel HOC invece del componente spostato. (come una pagina di caricamento). Voglio aggiungerlo presto alla mia libreria, non ho ancora avuto il tempo – mjrussell

+0

In realtà sono riuscito a risolvere il problema senza ricorrere a una pagina centrale. Ho usato redux-thunk, che rende l'azione in attesa di risoluzione, quindi aggiorno lo stato e quindi reindirizzo. Spero che questo abbia senso, ma se hai un problema simile, controlla [redux-thunk] (https://github.com/gaearon/redux-thunk). Ho anche trovato questo repo molto utile poiché stava facendo ciò che volevo implementare [HOC con autenticazione] (https://github.com/joshgeller/react-redux-jwt-auth-example) – Abdi