2017-11-18 21 views
0

Ich erstelle eine neue React Single-Page-Anwendung und versuche, mit Auth0 zu integrieren. Ich habe mit dem React-Beispiel gearbeitet, kann aber scheinbar nicht richtig funktionieren, sodass Sie sich sofort nach dem Laden der App anmelden müssen. Das Problem, das ich jetzt habe, besteht darin, dass Sie zweimal zur Anmeldeseite weitergeleitet werden, da die App vor dem ersten Ausführen der Authentifizierung gerendert wird. Dies sind die wichtigen Teile des Codes:React/Redux/Router - Auth0 Login beim Laden

index.js:

function initAuth(callback) { 

    const auth = store.getState().app.auth; 

    if(!auth.isAuthenticated()) { 
    auth.login(); 
    } 

    callback(); 

} 

//Authorize the app and then render it 
initAuth(function() { 
    render(
    <Provider store={store}> 
     <ConnectedRouter history={history}> 
     <div> 
      <App /> 
     </div> 
     </ConnectedRouter> 
    </Provider>, 
    target 
); 
}); 

app.js:

const App = props => (
    <div> 
    //... Other stuff 
    <Routes/> 
    //... More stuff 
    </div> 
); 

routes.js:

const Routes = props => (
    <main> 
    <Switch> 
     //...Other Routes Are Here 
     <Route path="/callback" render={(props) => { 
     return <Callback data={props} {...props} />; 
     }}/> 
     <Redirect from='*' to='/'/> {/*Any unknown URL will go here*/} 
    </Switch> 
    </main> 
); 

callback.js:

const auth = store.getState().app.auth; 

const handleAuthentication = (nextState) => { 
    console.log('Evaluation: ', /access_token|id_token|error/.test(nextState.location.hash)) 
    if (/access_token|id_token|error/.test(nextState.location.hash)) { 
    auth.handleAuthentication(); 
    } 
}; 

class Callback extends Component { 

    componentDidMount() { 
    handleAuthentication(this.props.data); 
    } 
    //... Render method etc 
} 

auth.js:

login() { 
    this.auth0.authorize(); 
} 

handleAuthentication() { 
    this.auth0.parseHash((err, authResult) => { 
    if (authResult && authResult.accessToken && authResult.idToken) { 
     this.setSession(authResult); 
     history.replace('/home'); 
    } else if (err) { 
     history.replace('/home'); 
     alert(`Error: ${err.error}. Check the console for further details.`); 
    } 
    }); 
} 

isAuthenticated() { 
    // Check whether the current time is past the 
    // access token's expiry time 
    let expiresAt = JSON.parse(localStorage.getItem('expires_at')); 
    return new Date().getTime() < expiresAt; 
} 

Gerade jetzt meine App funktioniert im Grunde. Das einzige Problem besteht darin, dass Sie sich zweimal anmelden müssen, da zwischen der Anmeldeantwort und dem Laden/Prüfen der App eine Race-Bedingung besteht. Warum es passiert, macht Sinn, aber ich bin mir nicht sicher, wie ich es am besten beheben kann.

Antwort

0

Ich halte ein Flag auf Zustand, der anzeigt, dass die Anwendung bootet. Dieses Flag ist wahr, bis einige Überprüfungen durchgeführt wurden, einschließlich der Überprüfung, ob der Benutzer bereits authentifiziert ist. Dies verhindert das Rendern von Komponenten und zeigt nur eine Ladeanzeige an. Sobald das Boot-Flag auf "false" gesetzt wurde, wird der Router rendern.