3

I am new in Mongoose. I'm developing a MEAN stack To do list with user authentification.

(In other words, a user can register login and create, get, update and delete the to do's).

It means 2 schemas: 'users' and 'tasks' With a relationship one to many: a user can have many tasks, many tasks belongs to a user.

This is how it looks the 'tasks' Schema:

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

In order to build the CRUD methods I will need the user._id as a 'owner' attribute, otherwhise any user could have access to the tasks list, create update or delete a task,

To get the user._id it I was thinking two options:

  1. Angular2 at the front end would get the user._id from the localStorage of the browser where was stored previously to keep the user logged in.

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

    And then send it in the same object as I send the 'title' attribute. I think this option is too insecure as anyone from the front-end could send any id.

  2. Get the current user._id at the back-end from the sessions. (I would't know how to do it though). And include it in the new task object at the POST method, something like this:

.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);
    });
}

});

Taking the second option (unless the former is better), how would you build the POST method? Concretely, how can I get the current user._id from the session and include it the new Task object?

I look forward of receiving your feedback soon. Thank you.

Carlos Alvarez
  • 41
  • 1
  • 1
  • 6

2 Answers2

1

A bit different but:

User Model:

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

Tasks Model:

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

module.exports = mongoose.model("Task", taskSchema);

Create a task with post route:

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
});

Similarly with edit/update you can use a put route (edit) and delete route (method override for delete) with a 'checkTaskOwnership' middleware and then

Task.findByIdAndUpdate / Task.findByIdAndRemove
jnelson
  • 11
  • 2
1

I think you should store user's _id in session. To store _id in the session use passport. It handles Authentication really well, and on successful authentication it stores users credentials in req.user. This req.user is present in all the requests. So for any Route, you can get the user's _id from req.user object. you wont need to send user's _id from the Frontend.

While saving Task use this:

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

task.save(function(err){...});

Read PassportJS docmentation to get more detailed information about Session and Authentication.

Ravi Shankar Bharti
  • 8,922
  • 5
  • 28
  • 52