React JS身份验证最佳实践

4

当用户未登录时,我如何防止React路由被调用?

想要在调用 / 时显示一个带有登录表单的单页面。

只有在用户已登录的情况下才能调用其他每个路由。

谢谢。

index.js

const render = () => {
    ReactDOM.render(
        <Provider store={store}>
            <AppContainer>
                <Router history={createHistory}>
                    <div>
                        <div className={t.topBar}>
                            <TopBarHelper/>
                        </div>

                        <div className={css.sidebararound}>
                    </div>
                   <Route exact path="/" component={Login}/>
                   <PrivateRoute  path="/dashboard" component={Dashboard}/>

....

const fakeAuth = {
    isAuthenticated: false,
    authenticate(cb) {
        this.isAuthenticated = true
        setTimeout(cb, 100) // fake async
    },
    signout(cb) {
        this.isAuthenticated = false
        setTimeout(cb, 100)
    }
}

const AuthButton = withRouter(({ history }) => (
    fakeAuth.isAuthenticated ? (
        <p>Welcome!</p>
    ) : (
        <p>You are not logged in.</p>
    )
))

登录代码在一个单独的文件中,代码如下:

class Login extends Component {
    constructor(props) {
        super(props);
        this.changeHandler = this.changeHandler.bind(this);
        this.state = {
            activeSnackbar: false,
            snackbarText: '',
            redirectToReferrer: false
        };
    }

    componentDidMount() {
        this.getData()
    };

    /**
     * Fetches all Data needed for this view
     */
    getData() {
        console.log(this.props)
    };

    /**
     * Handle Change
     * @param field
     * @param value
     */
    changeHandler(value, {target: {name, type}}) {
        this.setState({
            [name]: type === 'number' ? parseInt(value, 10) : value,
        });
    }

    /**
     * Submit new Ticket Form
     * @param event
     */
    handleLogin = (event) => {

        this.context.router.push('/dashboard');
        // axios.post(API_URL + '/dashboard')
        //     .then((response) => {
        //     })
        //     .catch(function (error) {
        //         console.log(error);
        //     });
    };



    render() {
        return (
            <div>
                <div className={css.loginpanel}>
                    <div className={css.loginpanellogo}>
                        <img src={logo} width="200px"/>
                    </div>
                    <div className={css.loginpanelform}>

                        <h1><T value="user.login.welcome"/></h1>

                        <form id="login" method="POST" action="">
                            <Input type='email' label={<T value='user.login.email'/>} name='email' value={this.state.email} onChange={this.changeHandler}/>
                            <Input type='password' label={<T value='user.login.password'/>} name='password' value={this.state.password} onChange={this.changeHandler}/>
                            <br />
                            <Button icon='save' onClick={this.AuthButton} label={<T value="user.login.signin"/>} raised primary/>
                            <Button label={<T value="user.login.signup"/>} raised/>
                        </form>
                        <br/>
                    </div>
                </div>
            </div>
        );
    }
}

export default connect()(Login);

但是我无法从登录页面调用AuthButton函数

2个回答

2

您可以使用两种选项

  1. 您可以在以下位置检查用户是否已登录:
    <Route onChange={requireLogin}></Route>
  2. 或者您可以在单个路由上检查

<Route onEnter={requireLogin}/>

/>


2
使用react-router-4,它可能会像这样显示:
<PrivateRoute path="/protected" component={Protected}/>

and

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={props =>
    fakeAuth.isAuthenticated 
      ? <Component {...props}/>
      : <Redirect to={{
          pathname: '/login',
          state: { from: props.location }
        }}/>
  )}/>
)

基本思想是拦截转换,检查身份验证并进行相应的重定向。
完整示例请参见此处

私有路由运作良好,看起来不错。但是从示例中登录无法正常工作。我在上面添加了我的完整代码。 - Felix
上面添加了一个index.js文件,其中包含路由和登录表单在另一个文件中。 - Felix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接