I am trying to update a user using jwt token in postman and i am getting this error (cannot read property id of undefined)

Viewed 706

I try this code using lama dev on youtube. and I am getting this error on postman i copy the access token and wher i use it, it display( token is not valid), but is this same token as the user, as the video.

when i look in the terminal it shows( cannot read property id of undefined) or cannot read property isAdmin of undefined)

I dont know how to solve it, if the problem is the code or i dont know how to use postman. I AM A NOVICE IN CODE

this is route file named verifytoken.js

const jwt = require("jsonwebtoken")

const verifyToken = (req,res, next) => {
    const authHeader = req.headers.token
    if(authHeader) {
            const token = authHeader.split("     ")[1];
        jwt.verify(token, process.env.JWT_SEC, (err, user)=>{
            if(err) res.status(403).json("token is not valid");
            req.user = user;
            next();
        })
    } else {
        return res.status(401).json(" you are not authenticated");
    }
};
const verifyTokenAndAuthorization = (req,res,next) => {
    verifyToken(req,res,()=> {
        if(req.user.id === req.params.id || req.user.isAdmin ) {
        next();
    } else {
        res.status(403).json("you are not allowed to do that");
    }
    });
};
const verifyTokenAndAdmin = (req,res,next) => {
    verifyToken(req,res,()=> {
        if( req.user.isAdmin) {
        next();
    } else {
        res.status(403).json("your are not the admin ");
    }
    });
};

module.exports = {verifyToken, verifyTokenAndAuthorization, verifyTokenAndAdmin};
  • this is route file named user.js*


const User = require("../models/User")
const { verifyToken, verifyTokenAndAuthorization, verifyTokenAndAdmin} = require("./verifyToken");


const router = require("express").Router();

// UPDATE
router.put("/:id", verifyTokenAndAuthorization, async (req, res)=>{
    if(req.body.password) {
        req.body.password = CryptoJS.AES.encrypt(
            req.body.password,
             process.env.PASS_SEC
            ).toString();
    }
    try {
        const updatedUser = await User.findByIdAndUpdate(req.params.id, {
            $set: req.body
        }, {new: true}
        );
        res.status(200).json(updatedUser);
    }catch (err) {
        res.status(500).json(err);
    }

});
//DELETE 

router.delete("/:id", verifyTokenAndAuthorization, async (req,res)=>{
    try {
        await User.findByIdAndDelete(req.params.id)
        res.status(200).json("user has been deleted");
    }catch(err){
        res.status(500).json(err)
    }
})

//GET USER

router.get("/find/:id", verifyTokenAndAdmin, async (req,res)=>{
    try {
        const user = await User.findById(req.params.id);
        const { password, ...others } = user._doc;
        res.status(200).json(others);
    }catch(err){
        res.status(500).json(err)
    }
})

module.exports = router;
3 Answers

I think this part has a problem:

if(authHeader) {
    const token = authHeader.split("     ")[1];
    jwt.verify(token, process.env.JWT_SEC, (err, user)=>{
       if(err) res.status(403).json("token is not valid");
            req.user = user;
            next();
        })
    } else {
        return res.status(401).json(" you are not authenticated");
    }

In this line: if(err) res.status(403).json("token is not valid");

You set the status to 403, but you continue with code execution. So even when your token is invalid you still invoke the next callback and try to read req.user. So my guess is that there's something wrong with your token. You should return straight away when there's an error: if(err) return res.status(403).json("token is not valid");

Also that split(" ") looks a bit suspicious. Why so many spaces? Are you sure this is ok?

I got the same problem, use if-else statement will solve this problem.
The express doc example looks like this.

if(err) { 
    res.status(403).json('Token is not valid');
} else { 
   req.user = user; 
   next();
}

I guess it may caused by the next() function, but i've look through the doc and couldn't got the reason.
If it doesn't work, try to kill your node process

In your auth.js file, change:

user && res.status(401).json("Wrong Credentials!");

To:

if (!user) {
  res.status(401).json("Wrong Credentials!");
  return;
}
Related