NodeJS + ReactJS: Как сделать весь маршрут приватным? - PullRequest
0 голосов
/ 26 августа 2018

В моей навигационной панели есть ссылка Категории , которая ведет к модели Категория .Только администратор может управлять этим разделом (модель).Я скрываю эту ссылку в виде.

Но когда я получаю прямой доступ к ссылке, например localhost: 3000 / category , страница начинает отображаться, а затем (примерно через 1 секунду)пользователь перенаправлен на домашнюю страницу.Однако - страница начнет отображаться, поэтому пользователь может некоторое время видеть содержимое, которое должно быть защищено.

Вот мой маршрут (NodeJS):

router.get('/', passport.authenticate('jwt', { session: false }), function(req, res, next) {
    if (req.isAuthenticated()) {
        console.log('logged in');
    } else {
        console.log('not logged in');
    }
    Category.find({}).sort('name').exec(function(err, categories) {
        if(err) throw err;
        res.send(JSON.stringify(categories));
    });
});

module.exports = router;

А вот компонент ReactJS:

class Category extends Component {
    constructor() {
        super();
        this.state = {
            name: '',
            errors: {},
            categories: []
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    componentDidMount() {
        let self = this;
        axios.get('/categories')
            .then(function(response) {
                self.setState({categories: response.data});
            }).catch(err => {
                if (err.response.status === 401) {
                    this.props.history.push('/');
                }
                return err;
            })
    }
    ...

Когда неавторизованный пользователь пытается посетить localhost: 3000 / category , NodeJS возвращает 401 и ReactJS перенаправляет этого пользователя на домашнюю страницу.Тем не менее - еще 1 секунда, когда пользователь увидит загрузку страницы защищенной категории.

Я думаю, что мой подход к решению этой ситуации не самый лучший (я новичок в MERN).Весь маршрут категория должен быть доступен только для администраторов.

Как мне решить эту проблему?

Спасибо

Ответы [ 2 ]

0 голосов
/ 26 августа 2018

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

function redirectIfAuth(nextState, replace) {
    const user = getCurrentUser(store.getState())
    console.log("User state: ", JSON.stringify(store.getState()));
    if (user.get('id')) {
        replace({
            pathname: 'dashboard'
        })
    }else{
       replace({
            pathname: 'login'
        })
    }
}

<Route path="categories" component={Categories}  onEnter={redirectIfAuth}/>

Код Nodejs:

Вы можете переместить запрос поиска категорий в блок else, а если пользователь не авторизован, вернуть относительный ответвнутри блока if.

router.get('/', passport.authenticate('jwt', { session: false }), function(req, res, next) {
    if (req.isAuthenticated()) {
        console.log('logged in');
    } else {
        Category.find({}).sort('name').exec(function(err, categories) {
           if(err) throw err;
           res.send(JSON.stringify(categories));
        });
    }

});

module.exports = router;

И несколько вещей, которые я хотел бы сказать вам, чтобы избежать ручного связывания функций / объектов и проблем с уровнем области действия

Начните использовать функцию стрелки, чтобы избежать проблем области действиявроде let self = this;

class Category extends Component {
    constructor() {
        super();
        this.state = {
            name: '',
            errors: {},
            categories: []
        }
    }

    componentDidMount() {
        axios.get('/categories')
            .then((response) => {
                this.setState({categories: response.data});
            }).catch(err => {
                if (err.response.status === 401) {
                    this.props.history.push('/');
                }
                return err;
            })
    }

    handleInputChange = () => {

    }

    handleSubmit = () => {

    }
0 голосов
/ 26 августа 2018

Может быть, вы можете попытаться добавить флаг загрузки и показывать содержимое вашего компонента, только если Ajax-вызов выполнен.

class Category extends Component {
    constructor() {
        super();
        this.state = {
            name: '',
            errors: {},
            categories: [],
            loading: true,
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    componentDidMount() {
        let self = this;
        axios.get('/categories')
            .then(function(response) {

                self.setState({
                    categories: response.data,
                    loading: false,
                });
            }).catch(err => {
                if (err.response.status === 401) {
                    this.props.history.push('/');
                }
                return err;
            })
    }

    render() {
        if (this.state.loading) {
            return <div />
        }

        return <ActualComponent />

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