【问题标题】:(Mongoose) How to get user._id from session in order to POST data including this user._id(Mongoose)如何从会话中获取 user._id 以便发布包含此 user._id 的数据
【发布时间】:2017-09-02 02:06:34
【问题描述】:

我是 Mongoose 的新手。 我正在开发一个带有用户身份验证的 MEAN 堆栈待办事项列表。

(换句话说,用户可以注册登录并创建、获取、更新和删除待办事项)。

这意味着 2 个模式:“用户”和“任务” 一对多关系:一个用户可以有很多任务,很多任务属于一个用户。

这是“任务”架构的外观:

const TaskSchema = new Schema({
        title:{
        type: String,
        required: true
        },
        owner:{
            type: Schema.Types.ObjectId,
            ref:'User'
        }
    });

为了构建 CRUD 方法,我需要 user._id 作为“所有者”属性,否则任何用户都可以访问任务列表、创建更新或删除任务,

为了得到 user._id 我在想两个选项:

  1. 前端的 Angular2 会从浏览器的 localStorage 中获取 user._id,以保持用户登录。

    const user = localStorage.getItem('user');

    然后将它发送到与我发送“标题”属性相同的对象中。 我认为这个选项太不安全了,因为前端的任何人都可以发送任何 id。

  2. 从会话中获取后端的当前 user._id。 (虽然我不知道该怎么做)。并将其包含在 POST 方法的新任务对象中,如下所示:

.post('/task', function(req, res, next){ function(req, res, next){

var task = new Task({
    title: req.body.title,
   owner : req.user._id     /// Does not do nothing
});

if(!task.title){
    res.status(400);
    res.json({
        "error":"Bad Data"
    });
} else{
    task.save(task, function(err, task){
        if(err){
            res.send(err);
        }
        res.json(task);
    });
}

});

采用第二个选项(除非前者更好),您将如何构建 POST 方法? 具体来说,如何从会话中获取当前 user._id 并将其包含在新的 Task 对象中?

我期待尽快收到您的反馈。 谢谢。

【问题讨论】:

    标签: node.js angular mongoose mean-stack mongoose-populate


    【解决方案1】:

    有点不同,但是:

    用户模型:

    var UserSchema = new mongoose.Schema({
        username: String,
        password: String
    });
    

    任务模型:

    var taskSchema = mongoose.schema({
        text: String,
        author: {
            id: {
                type: mongoose.Schema.Types.ObjectId,
                ref: "User"
            },
            username: String
        }
    });
    
    module.exports = mongoose.model("Task", taskSchema);
    

    使用发布路线创建任务:

    var text = req.body.text;
    var author = {
        id: req.user._id,
        username: req.user.username
    };
    
    var newTask = {text: text, author: author};
    
    Task.create(newTask, function(err, addedTask){
         // what you wanna do
    });
    

    与编辑/更新类似,您可以使用带有“checkTaskOwnership”中间件的放置路由(编辑)和删除路由(删除的方法覆盖),然后

    Task.findByIdAndUpdate / Task.findByIdAndRemove
    

    【讨论】:

    • 我刚刚遵循了您的建议,它显示的错误与我的相同:无法读取未定义的属性 '_id'
    • mongoose.Schema 中id 的类型和引用,req.user._id 可以解决问题。谢谢
    【解决方案2】:

    我认为您应该在会话中存储用户的_id。要在会话中存储_id,请使用passport。它可以很好地处理身份验证,并且在身份验证成功后,它将用户凭据存储在req.user 中。这个req.user 出现在所有请求中。因此,对于任何 Route,您都可以从 req.user 对象中获取用户的 _id。您不需要从前端发送用户的 _id。

    在保存Task时使用这个:

    var task = new Task({
        title: req.body.title,
       owner : req.user._id
    });
    
    task.save(function(err){...});
    

    阅读PassportJS docmentation 以获取有关SessionAuthentication 的更多详细信息。

    【讨论】:

      猜你喜欢
      • 2015-12-27
      • 1970-01-01
      • 1970-01-01
      • 2012-10-24
      • 2014-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-18
      相关资源
      最近更新 更多