Невозможно реализовать аутентификационные маршруты - PullRequest
1 голос
/ 27 апреля 2019

Я пытаюсь научиться реагировать и настраиваю маршруты в моем приложении, которые требуют, чтобы вы вошли в систему. Я пытаюсь адаптировать приведенный пример здесь

Код, который я написал, должен либо перенаправлять пользователя, либо отображать защищенный маршрут. Но когда я вхожу, меня все еще перенаправляют.

Я считаю, что проблема в моем классе PrivateRoute ниже. Я передаю ему свойство authenticated, которое устанавливается в родительском классе, но не обновляется.

В app.js мы объявляем аутентификатор, где мы выполняем асинхронный вход в систему с нашим бэкэндом.

Я передаю функцию checkLoggedIn компоненту входа в систему, где мы устанавливаем для свойства authenticated состояния родителя значение true. Я console.log() в состоянии просто проверить, что это происходит, и это так.

Когда я затем нажимаю маршрут от Link до /protected, я все еще перенаправлен.

app.js

// imports ... 

let authenticator = new Authenticator();

class ProtectedComponent extends Component {
    render() {
        return (
            <h1>Protected!</h1>
        );
    }
}

class App extends Component {
    constructor(props){
        super(props);
        this.state = {
            authenticator: authenticator,
            authenticated: authenticator.isLoggedIn(),
        }
    }

    checkLoggedIn() {
        this.setState({authenticated: true});
        console.log(this.state);
    }

    render() {
        let routes, links = null;
        links = <div className="links">
            <Link to="/login">Login</Link>
            <Link to="/protected">Protected</Link>
        </div>;

        routes = <div className="routes">
            <Route
                path="/login"
                render={() =>
                    <Login
                        authenticator={this.state.authenticator}
                        loginCallback={this.checkLoggedIn} />
                }
            />
            <PrivateRoute
                path="/protected"
                component={ProtectedComponent}
                authenticated={this.state.authenticated}
            />
        </div>;

        return (
            <Router className="App">
                {links}
                {routes}
            </Router>
        );
    }
}

export default App;

PrivateRoute.js

// imports .... 

const PrivateRoute = ({ component: Component, authenticated, ...rest }) => (
    <Route {...rest} render={props =>
            authenticated === true
                ? (<Component {...props} />)
                : (<Redirect to={{
                        pathname: "/login",
                        state: { from: props.location }
                    }} />
                )
    }/>
);

export default PrivateRoute;

Login.js

// imports ...

class Login extends Component {
    constructor(props) {
        super(props);
        this.authenticator = props.authenticator;
        this.loginCallback = props.loginCallback;
        this.state = {
            identifier: "",
            password: "",
        }
    }

    updateState = (e, keyName = null) => {
        this.setState({[keyName]: e.target.value})
    }

    attemptLogin = (e) => {
        this.authenticator.loginPromise(this.state.identifier, this.state.password)
            .then(resp => {
                if(resp.data.success === true) {
                    this.authenticator.setToken(resp.data.api_token);
                    this.loginCallback();
                } else {
                    this.authenticator.removeToken()
                }
            })
            .catch(err => {
                console.error(err);
            });
    }

    render(){
        <button onClick={this.attemptLogin}> Log In </button>
    }
}

export default Login;

Я устанавливаю аутентифицированное состояние в true в методе обратного вызова, но когда я перехожу к защищенному маршруту (и запускаю его метод рендеринга), кажется, что оно оценивается как false.

Если я неправильно понимаю систему реагирования, дайте мне знать. Если вы хотите увидеть больше кода, дайте мне знать, и я исправлю вопрос.

1 Ответ

1 голос
/ 27 апреля 2019

Сначала необходимо создать компонент HOC PrivateRoute:

import React from 'react';
import { Route, Redirect } from 'react-router-dom';

export const PrivateRoute = ({ component: Component, ...rest }) => (
    <Route {...rest} render={props => (
        localStorage.getItem('bpm-user')
            ? <Component {...props} />
            : <Redirect to={{ pathname: '/login', state: { from: props.location } }} />
    )} />
)

и обернуть маршруты, которые наиболее защищены:

        <Switch>
            <Route path="/login" component={Login} />
            <PrivateRoute path="/new/index" component={NewIndex} />
            <PrivateRoute path="/jobs/index" component={JobsIndex} />
            <PrivateRoute path="/unions/index" component={UnionsIndex} />
            <PrivateRoute exact path="/" component={ListIndex} />
            <PrivateRoute exact path="/charges" component={MunicipalCharges} />
        </Switch>

и использовать ссылку

<Link to="/jobs/index">Jobs</Link>

мой логин редуктор

import axios from 'axios';
import * as actionTypes from './AuthActionTypes';

export const login = (user) => {
    return dispatch => {
        // for example => dispatch({type:actionTypes.REQUEST_LOGIN_USER});
        axios({
            method: 'post',
            url: '/api/auth/login',
            data: { 'username': user.username, 'password': user.password },
            headers: { 'Content-Type': 'application/json;charset=utf-8' }
        })
            .then(res => {
                localStorage.setItem('bpm-user', JSON.stringify(res.data));
                dispatch({
                    type: actionTypes.LOGIN_USER,
                    payload: res.data
                })
            })
            .catch(error => {
                 // TODO... for example => dispatch({type:actionTypes.FAILD_LOGIN_USER, payload:error});
            })
    }
}

export const logout = () => {
    localStorage.removeItem('bpm-user');
}

как примеры кодов, которые я скопировал из моего собственного проекта

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...