9

私はを書いていますがが反応し、ルータ(v2.8.1)とES6構文を使用しての.jsアプリケーション(v15.3)に反応します。ユーザーが最初にログインする必要があるかどうかを確認するために、ページ間のすべてのトランジションをインターセプトするルータコードを取得できません。チェックでログインした場合 - ルータのApp ES6を反応させるの

私のトップレベル(アプリは、同様自明である)の方法は非常に簡単であるレンダリング:

render() 
    { 
     return (
     <Router history={hashHistory}> 
      <Route path="/" component={AppMain}> 
       <Route path="login" component={Login}/> 
       <Route path="logout" component={Logout}/> 
       <Route path="subject" component={SubjectPanel}/> 
       <Route path="all" component={NotesPanel}/> 
      </Route> 
     </Router> 
    ); 
    } 

すべてのWeb利用ES5コードのサンプルや反応し、ルータの古いバージョンを(古いバージョン2より) mixins(廃止予定)とwillTransitionTo(決して呼び出されない)の私の様々な試みは失敗しました。

グローバルな「インターセプタ機能」を設定して、ユーザーがリクエストしたページに着く前にユーザーを認証させるにはどうすればよいですか?

+0

私はここで同様の質問に対する答えを示しましたが、役に立つかもしれません。 http://stackoverflow.com/a/39098876/6060774 – alexi2

答えて

1

フォーカス取得時のコールバックのこのバージョンは、最終的に反応し、ルータ(V2.8)のために働い:

requireAuth(nextState, 
       replace) 
    { 
     if(!this.authenticated()) // pseudocode - SYNCHRONOUS function (cannot be async without extra callback parameter to this function) 
     replace('/login') 
    } 

をv2の対V1との間に反応し、ルータリダイレクトの違いを説明したリンクがhereです。以下に引用関連セクション:以下

Likewise, redirecting from an onEnter hook now also uses a location descriptor. 

// v1.0.x 
(nextState, replaceState) => replaceState(null, '/foo') 
(nextState, replaceState) => replaceState(null, '/foo', { the: 'query' }) 

// v2.0.0 
(nextState, replace) => replace('/foo') 
(nextState, replace) => replace({ pathname: '/foo', query: { the: 'query' } }) 

全コードリスト(反応し、ルータのバージョン2.8.1を):V4で

requireAuth(nextState, 
       replace) 
{ 
    if(!this.authenticated()) // pseudocode - SYNCHRONOUS function (cannot be async without extra callback parameter to this function) 
    replace('/login'); 
} 

render() { 
    return (
    <Router history={hashHistory}> 
     <Route path="/" component={AppMain}> 
      <Route path="login" component={Login}/> 
      <Route path="logout" component={Logout}/> 
      <Route path="subject" component={SubjectPanel} onEnter={this.requireAuth}/> 
      <Route path="all" component={NotesPanel} onEnter={this.requireAuth}/> 
     </Route> 
    </Router> 
); 
} 
6

すべてのルートには、ルート遷移が発生する前に呼び出されるonEnterフックがあります。カスタムrequireAuth関数を使用してonEnterフックを処理します。

<Route path="/search" component={Search} onEnter={requireAuth} /> 

サンプルrequireAuthを以下に示します。ユーザーが認証されている場合、next()経由で移行します。そうでなければパス名を/ loginで置き換えてnext()で置き換えます。ログインが現在のパス名にも渡されるので、ログインが完了した後、ユーザーは最初に要求されたパスにリダイレクトされます。

function requireAuth(nextState, replace, next) { 
    if (!authenticated) { 
    replace({ 
     pathname: "/login", 
     state: {nextPathname: nextState.location.pathname} 
    }); 
    } 
    next(); 
} 
+0

これはほとんど動作します。 requireAuthは正しく呼び出されますが、replace({pathname:...); hangs – DataMania

+0

replace()の後にnext()を入れるのを忘れました。 – vijayst

+0

next()関数が定義されていませんでしたが、答えが正しいトラックに置かれました – DataMania

1

あなただけの使用が認証されているかどうかを確認するルートコンポーネントを作成し、次のコンポーネントを返すが、もちろん次のコンポーネントは別のルートになる可能性がある。

import React, { Component } from 'react'; 
import PropTypes from 'prop-types'; 

import { connect } from 'react-redux'; 
import { bindActionCreators } from 'redux'; 
import { Route, Redirect } from 'react-router-dom'; 

import AuthMiddleware from 'modules/middlewares/AuthMiddleware'; 

class PrivateRoute extends Component { 
    static propTypes = { 
    component: PropTypes.func.isRequired, 
    isAuthenticated: PropTypes.bool, 
    isLoggedIn: PropTypes.func.isRequired, 
    isError: PropTypes.bool.isRequired 
    }; 

    static defaultProps = { 
    isAuthenticated: false 
    }; 

    constructor(props) { 
    super(props); 
    if (!props.isAuthenticated) { 
     setTimeout(() => { 
     props.isLoggedIn(); 
     }, 5); 
    } 
    } 

    componentWillMount() { 
    if (this.props.isAuthenticated) { 
     console.log('authenticated'); 
    } else { 
     console.log('not authenticated'); 
    } 
    } 
    componentWillUnmount() {} 

    render() { 
    const { isAuthenticated, component, isError, ...rest } = this.props; 
    if (isAuthenticated !== null) { 
     return (
     <Route 
      {...rest} 
      render={props => (
      isAuthenticated ? (
       React.createElement(component, props) 
      ) : (
       <Redirect 
       to={{ 
        pathname: isError ? '/login' : '/welcome', 
        state: { from: props.location } 
       }} 
       /> 
      ) 
     )} 
     /> 
    ); 
    } return null; 
    } 

} 

const mapStateToProps = (state) => { 
    return { 
    isAuthenticated: state.auth.isAuthenticated, 
    isError: state.auth.isError 
    }; 
}; 

const mapDispatchToProps = (dispatch) => { 
    return bindActionCreators({ 
    isLoggedIn:() => AuthMiddleware.isLoggedIn() 
    }, dispatch); 
}; 

export default connect(mapStateToProps, mapDispatchToProps)(PrivateRoute); 
関連する問題