2017-11-18 51 views
0

新しいReactシングルページアプリケーションを作成していて、Auth0と統合しようとしています。私はReactの例で作業していますが、正しく動作するように見えないので、アプリケーションが読み込まれた直後にログインする必要があります。私が今問題にしているのは、認証が初めて完了する前にアプリケーションがレンダリングされているため、ログインページに2度リダイレクトされるということです。React/Redux/Router - Auth0ログイン時のロード

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

今の私のアプリは基本的に動作します。唯一の問題は、ログイン応答とアプリの読み込み/確認の間に競合条件があるため、2度ログインする必要があることです。なぜそれが起こっているのは完璧な意味を持っていますが、私はそれをどのように修正するのがベストかわかりません。

答えて

0

私はアプリケーションが起動していることを示すフラグをstateに保持します。このフラグは、ユーザーがすでに認証されているかどうかを確認するなど、いくつかのチェックが行われるまで真です。 これはコンポーネントのレンダリングを防ぎ、ローディングインジケータを表示するだけです。起動フラグがfalseに設定されると、ルータはレンダリングします。

関連する問題