NodeJS + ReactJS:如何将整个路由设为私有?

时间:2018-08-26 05:52:08

标签: node.js reactjs authentication

在我的导航栏中,我有一个名为 Categories 的链接,该链接指向一个模型 Category 。只有管​​理员可以管理此部分(模型)。我将此链接隐藏在视图中。

但是,当我直接访问链接(例如 localhost:3000 / categories )时,页面将开始呈现,然后(大约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 /类别时,NodeJS返回 401 ,ReactJS在首页上将该用户重定向。但是,当用户看到正在加载受保护的类别页面时,仍然还有大约1秒的时间。

我认为我解决这种情况的方法不是最好的(我是MERN的新手)。整个路线类别应该仅适用于管理员。

如何解决此问题?

谢谢

2 个答案:

答案 0 :(得分:0)

也许您可以尝试添加加载标志,并且仅在Ajax调用完成后才显示组件内容。

mailto

答案 1 :(得分:0)

防止在未授权用户时显示类别。如果您使用的是react-router,请查看以下解决方案

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 = () => {

    }