猫鼬在更新之前先检查用户是否拥有文档

时间:2019-08-16 23:35:43

标签: node.js mongodb express mongoose

我试图在更新之前检查用户是否拥有文档,并希望将其保留为DRY。理想情况下,我不必必须先对数据库进行两次调用,而我将首先findById().then(doc => {check if user owns document and then -> doc.findByIdAndUpdate() })进行一次调用,而不必将其作为对数据库的一次调用。

我一直不得不在 express route 上执行此检查,并考虑过在猫鼬.pre('update')中间件上实现这一层逻辑。但是不知道如何将传入的用户ID req对象传递给我的中间件验证功能?

是否有更好的层可以实现此检查功能?还是我每次要检查用户是否拥有文档并在每条快速路线中将其写出时都必须向数据库发出两个请求?

我当前的实现是:

const addDocToDoc = (req, res, next) => {
    let doc1id = req.params.id;
    let doc2id  = req.params.doc2id;
    Doc1.findById(doc1id)
        .then(doc1 => {
            if(userCanAlter(doc1, req.user, res)) {
                doc1.doc2s.push(doc2id)
                return doc1.save().then(updatedDoc1 => res.send(updatedDoc1))
            }
        }).catch(next)
}

userCanAlter()如下所示:

function userCanAlter(instance, user, res) {
        if (!instance) { res.status(404).send("Document does not exist."); return false}
        if (instance.user != user) { res.status(401).send("User unauthorized"); return false}
        else return true;
    }

显然,这是一个非常简单的更新,但是更复杂的更新在保存之前需要更多的配置。

2 个答案:

答案 0 :(得分:0)

您只需在 find 查询中包装用户并使用 findOne(),如下所示:

const addDocToDoc = (req, res, next) => {
    const {
        user = ''
    } = req;
    const {
        id = '', doc2id = ''
    } = req.params;
    Doc1.findOne({
            _id: id,
            user
        })
        .then(doc => {
            if (!doc) {
                return res.status(400).json({
                    message: 'User Not Found!!'
                });
            }
            doc.doc2s.push(doc2id);
            doc.save()
                .then(updatedDoc1 => res.status(200).json(updatedDoc1))
                .catch(err => res.status(500).json({
                    message: 'Error While Updating!!',
                    error: err
                }));
        })
        .catch(err => res.status(500).json({
            message: 'Error While Fetching!!',
            error: err
        }));
}

此外,我建议您是否花点时间来命名事物,因为这可能使事情混乱几次。

如果您想为未经授权的用户抛出特定错误,可以坚持执行,只是不需要单独的方法来检查所有权。我用async / await简化了它,代码是:

const addDocToDoc = async (req, res, next) => {
    try {
        const {
            user = ''
        } = req;
        const {
            id = '', doc2id = ''
        } = req.params;
        const doc = await Doc1.findById(id);
        if (!doc || !doc.user || doc.user !== user) {
            return res.status(401).json({
                message: 'Unauthorized User!!'
            });
        }
        doc.doc2s.push(doc2id);
        const updatedDoc1 = await doc.save();
        return res.status(200).json(updatedDoc1);
    } catch (err) {
        res.status(500).json({
            message: 'Error While Updating Record!!',
            error: err
        });
    }
}

Ps:您可能需要进行一些修改,因为我没有机会运行它。

希望这会有所帮助:)

答案 1 :(得分:0)

有问题的当前实施是最佳和DRY的最佳实施。

相关问题