简体   繁体   中英

Cannot read properties of undefined (reading 'id')

I have a auth.js file And a middleware named as fetchuser code given beolow Can anyone please tell me why am i getting this error.

I am using express js and mongoose but this error is occured during sending token to the user and verify the user whether is user logged in or not.

auth.js

const express = require('express');
const User = require('../models/User');
const router = express.Router();
const { body, validationResult } = require('express-validator');
const bcrypt = require('bcryptjs'); // it is used for password hashing 
const jwt = require('jsonwebtoken');
const fetchuser=require('../middleware/fetchuser');

// Route:1 - Create a User using :POST.  "/api/auth/createuser".   NO Login Required.
router.post('/createuser', [
  body('email', 'Enter valid email').isEmail(),
  body('name', 'Enter valid email').isLength({ min: 3 }),
  body('password').isLength({ min: 5 })
], async (req, res) => {
  // Check fo vaidation whether is any rule(defined in User model) breaked or not
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }

  // Check Whether user with same email id exist or not
  try {
    let user = await User.findOne({ email: req.body.email });
    if (user) {
      return res.status(400).json({ error: "Sorry user with same email id already exist" });
    }

    // hashing of password
    const salt = await bcrypt.genSalt(10);
    const securePassword = await bcrypt.hash(req.body.password, salt);

    // create A new User
    user = await User.create({
      name: req.body.name,
      email: req.body.email,
      password: securePassword
    })

    // returning user id in Token
    const JWT_secret = "Rishiisa@boy";
    const data = { user:{id: user.id} };
    const auth_token = jwt.sign(data, JWT_secret);
    res.json({ auth_token });
  }
  catch (error) {
    console.error(error.message);
    res.status(500).send("Internal server error");
  }
})


// Route:2 - Login a User using credential.  "/api/auth/login".   NO Login Required.
router.post('/login', [
  body('email', 'Enter valid email').isEmail(),
  body('password', 'password can not be blank').exists(),
], async (req, res) => {
  // Check for vaidation according to the rule defined at line no. 53, 54;
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }

  // destructure the email and password from body request
  const { email, password } = req.body;

  try {
    // Checking whether email is exist or not 
    let user = await User.findOne({ email });
    if (!user) {
      return res.status(400).json({ error: "Please try to login using correct credentials" });
    }

    // Now Comparing password with help of bcryptjs
    const comparepassword = await bcrypt.compare(password, user.password);
    if (!comparepassword) {
      return res.status(400).json({ error: "Please try to login using correct credentials" });
    }

    // Now if user enter coorect password and login then user got logged in;
    // And We will send authtoken to user;
    // returning user id in Token
    const JWT_secret = "Rishiisa@boy";
    const data = { user:{id: user.id} };
    const auth_token = jwt.sign(data, JWT_secret);
    res.json({ auth_token });
  }
  catch (error) {
    console.error(error.message);
    res.status(500).send("Internal server error");
  }

})


// Route:3 - Get Loggedin User details using:POST  "/api/auth/getuser"  Login required
router.post('/getuser', fetchuser, async (req, res) => {
  try {
    const userid = req.user.id;
    const user = await User.findById(userid).select("-password");
    res.send(user);
  } catch (error) {
    console.error(error.message);
    res.status(500).send("Internal server error");
  }
})

module.exports = router

middleware: fetchuser.js

const jwt = require('jsonwebtoken');
const JWT_secret = "Rishiisa@boy";

const fetchuser = (req, res, next) => {
  // Get the user from jwt token and add user id to req object
  const token = req.header('auth_token');
  if (!token) {
    res.status(401).send({ error: "Please authenticate using a valid token" });
  }
  try {
    const data = jwt.verify(token, JWT_secret);
    req.user = data.user;
    next();
  } catch (error) {
    res.status(401).send({ error: "Please authenticate using a valid token" });
  }

}

module.exports = fetchuser;

In auth.js, where you wrote: "const data = { user:{id: user.id} };" Try changing user.id to user._id, since in MongoDB the user id is referred to as '_id'.

Let me know if that works.

I've had problems sending jwt token back and even verifying it, but all is good on my side now.

Also, below is my (inspired) method of going about this:

router.post('/register', (req, res)=>{
    const { username, password } = req.body;

    const user = new User({
        username,
        password
    });

    bcrypt.genSalt(10, (err, salt)=>{
        bcrypt.hash(user.password, salt, (err, hash)=>{
            if(err) throw err;
            user.password = hash;
            user.save()
                .then(user=>{

                    jwt.sign(
                        { id: user._id },
                        process.env.jwtSecret,
                        { expiresIn: 3600 },
                        (err, token) =>{
                            if(err) throw err;
                            res.status(200)
                        }
                    )

                    
                })
        })
    })

})

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