【问题标题】:TypeError: Cannot read property 'jwtoken' of undefined at AuthenticateTypeError:无法在身份验证时读取未定义的属性“jwtoken”
【发布时间】:2026-01-20 04:05:01
【问题描述】:

我正在尝试使用 jwt 对用户进行身份验证并发现此错误。这是一个 MERN 项目,在显示秘密页面之前,我必须验证我已将其数据存储在 MongoDb 中的用户。

VSCode 突出显示的其他错误是:

1.当我将鼠标悬停在._id (authentication.js)上时

const rootUser=await User.findOne({_id:verifyToken._id,"tokens.token":token})

类型'string | JwtPayload' 上不存在属性'_id'

2.当我将鼠标悬停在req.rootUser(app.js)上时

res.send(req.rootUser)

类型“Request<{}, any, any, ParsedQs, Record<string, any>>”上不存在属性 'rootUser'

我的代码如下:

app.js

const mongoose = require('mongoose')
const dotenv = require('dotenv')
const bcrypt = require('bcryptjs')
const jwt=require('jsonwebtoken')
const app = express()
const router = express.Router();
const port = 5000
const authenticate=require("./middleware/authenticate")

dotenv.config({ path: './config.env' })
const DB = process.env.DATABASE;
app.use(express.json());
const User = require('./model/userSchema')



mongoose
  .connect(DB, {
    useUnifiedTopology: true,
    useNewUrlParser: true,

  })
  .then(() => console.log('Database connected.'))
  .catch(err => console.log(err));





app.get('/', (req, res) => {
  res.send('Hello World!')
  console.log("hey")
})
app.post('/register', async (req, res) => {
  const { name, email, work, phone, password, cpassword } = req.body;
  if (!name || !email || !work || !phone || !password || !cpassword) {
    return res.status(422).json({ error: "Form Not Properly Filled" });
  }
  try {
    const userExist = await User.findOne({ email: email })
    if (userExist) {
      return res.status(422).json({ error: "Email ALready Exists" })
    }
    else if (password != cpassword) {
      return res.status(422).json({ error: "Password does not match" })
    }
    else {
      const user = new User({ name, email, work, phone, password, cpassword })
      await user.save()
      res.status(201).json({ message: "user registered successfully" })
    }



  } catch (error) {
    console.log(error);
  }




})

//login route
app.post('/signin', async (req, res) => {
  try {

    let token;

    const { email, password } = req.body;
    if (!email || !password) {
      return res.status(400).json({ error: "Please fill the data correctly" })
    }
    const userLogin = await User.findOne({ email: email })
    console.log(userLogin);
  
    if (userLogin) {
      const isMatch = await bcrypt.compare(password, userLogin.password)
      token = await userLogin.generateAuthToken();
      console.log(token)

      res.cookie("jwtoken",token,{
        expires:new Date(Date.now()+25892000000),
        httpOnly:true

      })
      if (!isMatch) {
        res.status(400).json({ error: "Invalid Credentials" })
      }
      else {
        res.status(200).json({ message: "Login Success" })
      }
    }
    else {
      res.status(400).json({ error: "Invalid Credentials" })
    }

  } catch (error) {
    console.log(error)
  }
})

//about page request

app.get('/about',authenticate,  (req, res) => {
  console.log("About")
  res.send(req.rootUser)
})
app.get('/forget', (req, res) => {
  res.cookie("harsh","test")
  res.send('Forget World!')
})

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`)
})

验证.js

const User=require("../model/userSchema")

const Authenticate=async (req,res,next)=>{
try {
    console.log(req.cookies)
    const token=req.cookies.jwtoken;
    console.log("below")
    const verifyToken =jwt.verify(token,process.env.SECRET_KEY)
    console.log(verifyToken)
    const rootUser=await User.findOne({_id:verifyToken._id,"tokens.token":token})
    if(!rootUser){
        throw new Error("User Not Found")
    }
    req.token=token;
    req.rootUser=rootUser;
    req.userID=rootUser._id;
    next();
} catch (error) {
    res.status(401).send('Unauthorized : No token provided')
    console.log(error)
}
}
module.exports=Authenticate;

userSchema.js

const mongoose=require('mongoose')
const bcrypt=require('bcryptjs')
const jwt=require('jsonwebtoken')

const userSchema=new mongoose.Schema({
     name:{
         type:String,
         required:true,
     },
     email:{
        type:String,
        required:true,
    },
    phone:{
        type:String,
        required:true,
    },
    work:{
        type:String,
        required:true,
    },
    password:{
        type:String,
        required:true,
    },
    cpassword:{
        type:String,
        required:true,
    },
    tokens:[
        {
            token:{
                type:String,
                required:true,
            }
        }
    ]
})


userSchema.pre('save' , async function(next){
    console.log("inside hash")
    if(this.isModified('password')){
        this.password=await bcrypt.hash(this.password,12)
        this.cpassword=await bcrypt.hash(this.cpassword,12)
    }
    next();
})

userSchema.methods.generateAuthToken = async function(){
    try {
        let token =jwt.sign({_id:this._id},process.env.SECRET_KEY)
        this.tokens=this.tokens.concat({token : token})
        await this.save();
        return token
    } catch (error) {
        console.log(error)
    }
}

const User=mongoose.model('USER',userSchema);
module.exports=User;

【问题讨论】:

    标签: node.js express mongoose cookies jwt


    【解决方案1】:

    1。用户登录时生成 JWT 令牌

    生成令牌并将此令牌与响应一起发送...

        router.post("/login", async (req, res) => {
          try {
            // checking username
            const user = await User.findOne({ email: req.body.email });
            !user && res.status(401).json("Wrong Username");
        
            // checking password
            const bytes = CryptoJS.AES.decrypt(user.password, process.env.SECRET_KEY);
            const originalPassword = bytes.toString(CryptoJS.enc.Utf8);
        
            // If password not match return respond
            originalPassword !== req.body.password &&
              res.status(401).json("Wrong Password");
        
            // Creating Json Web Token
        
            const accessToken = jwt.sign(
              { id: user._id, isAdmin: user.isAdmin },
              process.env.SECRET_KEY,
              { expiresIn: "5d" }
            );
        
            // stop sending password to respond
            const { password, ...info } = user._doc;
        
            // Returning User(info) , also sending accessToken
            res.status(200).json({ ...info, accessToken });
          } catch (err) {
            res.status(500).json(err);
          }
        });
    

    2。验证令牌中间件

    创建此验证令牌函数,在您的路由中用作 MIDDLEWARE...

    const jwt = require("jsonwebtoken");
    
    function verify(req, res, next) {
      const authHeader = req.headers.token;
      if (authHeader) {
        const token = authHeader.split(" ")[1];
        jwt.verify(token, process.env.SECRET_KEY, (err, user) => {
          if (err) res.status(403).json("Token is not valid");
          req.user = user;
          next();
        });
      } else {
        return res.status(402).json("You are not authorized");
      }
    }
    
    module.exports = verify;
    

    3。验证路由作为中间件

    const verify = require("../verifyToken");
    
    // CREATE
    router.post("/", verify, async (req, res) => {
      if (req.user.isAdmin) {
        const newList = new List(req.body);
        try {
          const savedList = await newList.save();
          res.status(201).json(savedList);
        } catch (error) {
          res.status(500).json(err);
        }
      } else {
        res.status(403).json("You are not allowed!");
      }
    });
    
    // DELETE
    router.delete("/:id", verify, async (req, res) => {
      if (req.user.isAdmin) {
        try {
          await List.findByIdAndDelete(req.params.id);
          res.status(201).json("The list has been deleted");
        } catch (err) {
          res.status(500).json(err);
        }
      } else {
        res.status(403).json("You are not allowed!");
      }
    });
    

    结论:-

    1. 在用户登录时使用 jwt.sign 创建令牌...
    2. 在根目录下创建验证函数导出此函数...
    3. 需要在路由文件中使用此函数作为中间件...

    【讨论】:

    • 我根据你的编辑了我的代码,但我仍然得到 res.status(402).json("You are not authorized");来自中间件文件的错误。我试图找出它发生的原因,然后当我尝试在控制台上记录它时发现我的 authHeader 的值未定义,因此它向我发送 402 响应。我的令牌是使用您的代码生成并发送的 const { password, ...info } = user._doc; res.status(200).json({ ...info, accessToken });
    最近更新 更多