简体   繁体   中英

Getting an error "Cannot read properties of undefined (reading 'id') "

I am creating a webtoken for my backend API and to update my database. Even though the token and ID given to it are correct, it's return an error “token not valid” in the POSTMAN. When I checked the console it showed an error stating that “TypeError: Cannot read properties of undefined (reading 'id')”.The code to it is shown below.

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

module.exports = { verifyToken,verifyTokenAndAuthorization };



the code to the user module is given below

const User = require("../models/User.js");
const { verifyTokenAndAuthorization } = require("./verifyToken.js");
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);
  }
});
module.exports = router;

In your verifyToken() function you call another function jwt.verify() like so:

jwt.verify(token, process.env.JWT_SEC, (err, user) => {
      if (err) res.status(403).json("Token is not valid!");
      req.user = user;
      next();
    });

What is happening is jwt.verify() has found an error. So when it invokes your callback function:

(err, user) => {
      if (err) res.status(403).json("Token is not valid!"); // this is the problem!
      req.user = user;
      next();
    }

You are saying if there is an error, send a response of 403. Okay fine. BUT nothing stops your code from running after this point. So you have sent a 403 response, but are still setting req.user = user (which is probably undefined) and calling next()

What is next() ? You have defined next as:

() => {
    if (req.user.id === req.params.id || req.user.isAdmin) {
      next();
    } else {
      res.status(403).json("You are not allowed to do that!");
    }
  }

So req.user is undefined, and you are trying to see if req.user.id === req.params.id . At runtime this is actually equivalent to undefined.id === req.params.id

So in short, you need to make sure you are exiting your code correctly. A simple solution to this a small change to your current code:

jwt.verify(token, process.env.JWT_SEC, (err, user) => {
      if (err) {
        // Could throw an error here, catch and then send the response too.
        res.status(403).json("Token is not valid!"); 
      } else {
         req.user = user;
         next();
      }
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM