ReactJS защищенный маршрут с вызовом API - PullRequest
0 голосов
/ 10 апреля 2019

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

Ниже вы можете увидеть мой файл маршрутов (app.js):

class App extends Component {
    render() {
        return (
            <div>
                <Header />
                <Switch>
                    <Route exact path="/" component={Home} />
                    <Route path="/login" component={Login} />
                    <Route path="/signup" component={SignUp} />
                    <Route path="/contact" component={Contact} />
                    <ProtectedRoute exac path="/user" component={Profile} />
                    <ProtectedRoute path="/user/person" component={SignUpPerson} />
                    <Route component={NotFound} />
                </Switch>
                <Footer />
            </div>
        );
    }
}

Мой защищенный файл:

const ProtectedRoute = ({ component: Component, ...rest }) => (
    <Route {...rest} render={props => (
        AuthService.isRightUser() ? (
            <Component {...props} />
        ) : (
            <Redirect to={{
                pathname: '/login',
                state: { from: props.location }
            }}/>
        )
    )} />
);

export default ProtectedRoute;

И моя функция isRightUser. Эта функция отправляет status(401), когда данные не действительны для зарегистрированного пользователя:

async isRightUser() {
    var result = true;
    //get token user saved in localStorage
    const userAuth = this.get();

    if (userAuth) {
        await axios.get('/api/users/user', {
            headers: { Authorization: userAuth }
        }).catch(err => {
            if (!err.response.data.auth) {
                //Clear localStorage
                //this.clear();
            }

            result = false;
        });
    }

    return result;
}

Этот код не работает, и я действительно не знаю, почему. Может быть, мне нужно вызвать мою функцию AuthService.isRightUser() с await перед вызовом и поставить мою функцию асинхронной?

Как я могу обновить свой код для проверки моего пользователя перед доступом к защищенной странице?

Ответы [ 2 ]

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

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

Внутри переключателя я использовал

<PrivateRoute 
    path="/path"
    component={Discover}
    exact={true}
/>

И мой класс PrivateRoute выглядит следующим образом

class PrivateRoute extends React.Component {

    constructor(props, context) {
        super(props, context);

        this.state = {
            isLoading: true,
            isLoggedIn: false
        };

        // Your axios call here

        // For success, update state like
        this.setState(() => ({ isLoading: false, isLoggedIn: true }));

        // For fail, update state like
        this.setState(() => ({ isLoading: false, isLoggedIn: false }));

    }

    render() {

        return this.state.isLoading ? null :
            this.state.isLoggedIn ?
            <Route path={this.props.path} component={this.props.component} exact={this.props.exact}/> :
            <Redirect to={{ pathname: '/login', state: { from: this.props.location } }} />

    }

}

export default PrivateRoute;
0 голосов
/ 10 апреля 2019

Когда вы аннотируете функцию с помощью async, как вы это сделали в AuthService.isRightUser(), она возвращает Promise, и вы соответственно не обрабатываете ответ метода.

Как вы предложили, вы можете вызвать метод AuthService.isRightUser() с помощью await и аннотировать передаваемую функцию свойству render с помощью async.

Или вы можете обработать ответ AuthService.isRightUser() с помощью .then() и .catch() вместо троичного оператора

...