Search code examples
node.jsjson-web-token

JWT improper decoding with mongoose data


Here is the data that i am encoding

{ _id: 5880c2562f109c2e17489155,
  password: '$2a$10$1TGM/Nnoii/ERt5YZFqaROJA0176bXw5wn7fF9B7.DrikVcW/Va4e',
  verified: false,
  __v: 0 }

and the data that i get from decoding using jsonwebtoken.

{ '$__': 
   { strictMode: true,
     getters: {},
     wasPopulated: false,
     activePaths: { paths: [Object], states: [Object], stateNames: [Object] },
     emitter: { domain: null, _events: {}, _eventsCount: 0, _maxListeners: 0 } },
  isNew: false,
  _doc: 
   { __v: 0,
     verified: false,
     password: '$2a$10$1TGM/Nnoii/ERt5YZFqaROJA0176bXw5wn7fF9B7.DrikVcW/Va4e',
     _id: '5880c2562f109c2e17489155' },
  _pres: 
   { '$__original_save': [ null, null ],
     '$__original_validate': [ null ],
     '$__original_remove': [ null ] },
  _posts: 
   { '$__original_save': [],
     '$__original_validate': [],
     '$__original_remove': [] },
  iat: 1484834592 }

If you notice the docs i should be able to access the decoded password field using decoded.password but from this case i have to use decoded._doc.password. Is this happening somehow because i am directly passing in the mongoose object into jwt or the output is fine and i should access the data by adding _doc. The relevant code is

module.exports['generateToken'] = (data)=>{
  return new Promise((fullfill,reject)=>{
    console.log(data.user);
    var token = jwt.sign(data.user,'shhhhhh');
    fullfill(token);
  });
}

module.exports['decodeToken'] = (token)=>{
 return new Promise((fullfill,reject)=>{
   jwt.verify(token,'shhhhhh',(err,decoded)=>{
     if(err)
       reject(err);
     console.log(decoded);
     fullfill(token);
   });
 });
}

data.user is the document that i got from mongoose query findOne.


Solution

  • Is this happening somehow because i am directly passing in the mongoose object into jwt

    Yes, instances of mongoose models have quite complicated structure inside. And _doc is a reference to an internal document.

    To avoid accessing by ._doc, you should encode document converted to a plain object:

    module.exports['generateToken'] = (data)=>{
      return new Promise((fullfill,reject)=>{
        console.log(data.user);
        var token = jwt.sign(data.user.toObject(),'shhhhhh');
        fullfill(token);
      });
    }