反应路由器v4身份验证令牌保持重定向到/

时间:2017-04-27 09:06:00

标签: reactjs react-router react-router-redux

首先,这是我的代码:

Routes.js

import React from 'react';
import PropTypes from 'prop-types';
import { Redirect, Route } from 'react-router-dom';
import { PUBLIC_ROUTE, LOGIN_ROUTE } from './utils/constants';

const routes = ({ component: Component, ...rest }) => {
    let { requireAuth, isAuthenticated } = rest;

    if (!requireAuth) {
        requireAuth = false;
    }

    // If user authenticated
    if (isAuthenticated) {
        // If page need auth
        if (requireAuth === true) {
            return (
                <Route {...rest} render={props => <Component {...props} />} />
            );
        } else if (requireAuth === 'partial') { // If the page is doesn't require auth but can't be access if auth true
            return <Redirect to={PUBLIC_ROUTE} />;
        }

        // If page doesn't need auth
        return <Route {...rest} render={props => <Component {...props} />} />;
    }

    // If user not authenticated //

    // page doesn't require Auth
    if (requireAuth === false || requireAuth === 'partial') {
        return <Route {...rest} render={props => <Component {...props} />} />;
    }
    // If page require Auth redirect user to login routes
    return (
        <Route
            {...rest}
            render={props => (
                <Redirect
                    to={{
                        pathname: `${LOGIN_ROUTE}`,
                        state: { from: props.location },
                    }}
                />
            )}
        />
    );
};

routes.propTypes = {
    component: React.PropTypes.oneOfType([
        React.PropTypes.element,
        React.PropTypes.func,
    ]),
};

export default routes;

App.js

const history = createHistory();

const mapStateToProps = state => {
    const { auth, global } = state;
    const { authenticated, user } = auth;
    const { loading } = global;

    return { authenticated, user, loading };
};

const reduxConnector = connect(mapStateToProps, { ping });

class App extends Component {
    state = {
        isAuthenticated: false,
    };
    static propTypes = {
        authenticated: PropTypes.bool.isRequired,
    };

    componentWillReceiveProps(nextProps) {
        this.setState({ isAuthenticated: nextProps.authenticated });
    }

    render() {
        const { authenticated, user, loading } = this.props;
        const { isAuthenticated } = this.state;

        if (loading) {
            return (
                <div style={style.center}>
                    <MDSpinner />
                </div>
            );
        }

        return (
            <ConnectedRouter history={history}>
                <div>
                    <NotificationsSystem theme={theme} />
                    <Header isAuthenticated={isAuthenticated} user={user} />
                    <NavMobile />
                    <SideMenu />
                    <Nav />

                    <Switch>
                        <Routes
                            requireAuth={false}
                            isAuthenticated={isAuthenticated}
                            exact
                            path="/"
                            component={Welcome}
                        />

                        <Routes
                            requireAuth={true}
                            isAuthenticated={isAuthenticated}
                            path="/point"
                            component={Point}
                        />

                        <Routes
                            requireAuth="partial"
                            isAuthenticated={isAuthenticated}
                            path="/login"
                            component={Login}
                        />

                        <Routes render={() => <h3>No Match</h3>} />
                    </Switch>
                    <Footer />

                </div>
            </ConnectedRouter>
        );
    }
}

export default reduxConnector(App);

Login.js

import React from 'react';
import PropTypes from 'prop-types';
import { withRouter, Link, Redirect } from 'react-router-dom';
import { Field, reduxForm } from 'redux-form';
import { connect } from 'react-redux';
import cookie from 'react-cookie';

import { Headline, Section, renderField } from 'components';
import { ping } from 'redux/modules/auth';

function mapStateToProps(state) {
    const { authenticated } = state.auth;

    return { authenticated };
}

const reduxConnector = connect(mapStateToProps, { ping });
const token = cookie.load('_t');

class Login extends React.Component {
    static defaultProps = {
        loggingIn: false,
        authenticated: false,
    };

    componentDidMount(){
        if(cookie.load('_t')){
            this.props.ping();
        }
    }

    render() {
        const { handleSubmit } = this.props;

        const { from } = this.props.location.state || {
            from: { pathname: '/' },
        };


        if (this.props.authenticated) {
            return <Redirect to={from} />;
        }

        return  <div>
                <Headline title="Login" />
            </div>;
    }
}

export default withRouter(reduxConnector(reduxFormDecorator(Login)));

假设我已登录我的应用。我想要导航到/point(需要授权才能访问),在检查令牌(redirect)后,应用会/loginthis.props.ping(): 1.如果令牌有效:它会将我重定向回point页面。 2.如果令牌无效:它会将我重定向到login页。

问题:

  1. 检查并且令牌有效后,该应用始终会重定向到/。 我console.log我的const {from}结果是{pathname: "/point", search: "", hash: "", state: undefined, key: undefined}。它永远不会返回上一页(在这种情况下/point页面)。

  2. 如果我访问&#39; /&#39;它从不重定向登录以致电ping。我需要这个,因为我的标题显示了用户的全名。所以我需要将状态设置为redux。

  3. 任何解决方案?

1 个答案:

答案 0 :(得分:0)

首先,您应该了解在安装组件后Redirect工作一次。你不能在重新渲染中继续它。您可以改用history.push() API方法。

其次,我不确定我是否正确理解了您的解决方案,但似乎您想要将某些数据重定向到redux商店(无法找到您在哪里调度)减少行动)。如果这是真的,这是一个不好的做法。您可以在登录后在专门的操作中执行此操作,并且您不必将此逻辑与任何组件相关联,然后不需要重定向。