Search code examples
node.jsmongodbexpressmongooseuserid

Trying to get current logged in user tasks in Nodejs and MongoDB


I'm working on a project that enables the admin to assign tasks to different users, every users should only see his own tasks.

I tried doing that by using the user.id as key, when the user logs in we send a token, and that token includes the user_id and other user info, I'm trying to extract the id from that token and view tasks based on that.

Tasks Model

const TaksSchema = new Schema({
  user: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'users',
  },
  taskName: {
    name: String,
  },
  taskDesc: {
    name: String,
  },
  dateAssigned: {
    type: Date,
    default: Date.now,
  },
  requiredDate: {
    type: Date,
  },
  completed: { type: Boolean, default: false },
});

// Export Schema
module.exports = Tasks = mongoose.model('tasks', TaksSchema); 

User model

const UserSchema = new Schema({
  name: {
    type: String,
    required: true,
  },
  email: {
    type: String,
    required: true,
  },
  password: {
    type: String,
    required: true,
  },
  role: {
    type: String,
    enum: ['basic', 'admin'],
    default: 'basic',
  },
  avatar: {
    type: String,
  },
  date: {
    type: Date,
    default: Date.now,
  },
});

// Export Schema
module.exports = User = mongoose.model('users', UserSchema);

tasks route

router.get('/', (req, res) => {
  const errors = {};
  Tasks.findOne({ user: req.user.id })
    .populate('user', ['name', 'avatar'])
    .then((task) => {
      if (!task) {
        errors.notask = "There's no Tasks Right Now";
        return res.status(400).json(errors);
      }
      res.json(task).catch((err) => res.status(404).json(err));
    });
});

When I try sending the get request from postman I get this error

TypeError: Cannot read property 'id' of undefined

For security I'm sending the Id through JWT token. Here is the code

const payload = { id: user.id, name: user.name, avatar: user.avatar }; // Create jwt patload
        // Sign the token
        jwt.sign(
          payload,
          keys.secretOrKey,
          { expiresIn: 3600 },
          (err, token) => {
            res.json({ sucess: true, token: 'Bearer ' + token });
          }
        );

Solution

  • You must first verify/decode the ID in order to receive the payload.

    In the code, you are trying to access the id field from user. Actually you need to add a middleware which validates the JWT and appends the result in the user field.

    Example :

    middlewares/validateJwt.js

    Assuming you are sending JWT in the header as Bearer Token.

     try{
    
     let token = req.headers.authorization.split(" ")[1]; // Bearer <token>
     let result = jwt.verify(token, "JWT_SECRET", options);
     req.user = result;
     next();
    } catch...