You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express路由中ObjectId转换失败与读取undefined的_id属性错误求助

Express路由中ObjectId转换失败与读取undefined的_id属性错误求助

嘿,我帮你排查一下这两个错误的根源,咱们逐个解决:

第一个错误:Cast to ObjectId failed(authUser函数)

这个错误是因为你在验证用户时用错了Mongoose查询方法!你写的是:

const user = await User.findById({ email });

findById方法是专门用来根据_id字段查询文档的,你传了一个包含email的对象,Mongoose会尝试把这个对象转换成ObjectId类型,自然就失败了。

修复方法:把findById改成findOne,和注册用户时的查询逻辑一致:

const user = await User.findOne({ email });

第二个错误:Cannot read properties of undefined (reading '_id')(getUserProfile函数)

这个问题是因为req.user没有被正确赋值,导致读取req.user._id时报错,根源在三个地方:

1. 路由没有添加权限验证中间件

你的/profile路由没有使用protect中间件,所以请求不会经过token验证流程,req.user自然是undefined。
修复路由(routes/authRoutes.js):

router.get('/profile', protect, getUserProfile); // 加上protect中间件

2. authMiddleware里的几处语法错误

  • split('')应该是split(' '):Bearer和token之间是空格分隔,你用空字符串分割会把每个字符拆分开,导致token无效。
  • findBy是不存在的方法,应该用findById。
  • 解码后的字段是_id不是id:因为你生成token时用的是{ _id },所以decoded里的键是_id。

修复authMiddleware.js:

const protect = asyncHandler(async (req, res, next) => {
    let token;

    if(req.headers.authorization && req.headers.authorization.startsWith('Bearer')){
        try{
            token = req.headers.authorization.split(' ')[1]; // 改成split(' ')
            const decoded = jwt.verify(token, process.env.JWT_SECRET);
            req.user = await User.findById(decoded._id).select('-password'); // 改成findById和decoded._id
            next();
        } catch(err){
            console.log(err);
            res.status(401);
            throw new Error('Not authorized, token failed');
        }
    }

    if(!token){
        res.status(401);
        throw new Error('Not authorized, no token');
    }
});

其他需要修复的小问题

除了上面两个核心错误,还有几个细节问题会导致潜在bug:

1. Notes模型错误(models/Notes.js)

你导出时用了UserSchema,应该是NotesSchema:

const Notes = mongoose.model('Notes', NotesSchema); // 把UserSchema改成NotesSchema

2. errorMiddleware里的拼写错误

req.orginalUrl应该是req.originalUrl(少了一个i):

const error = new Error(`Not Found - ${req.originalUrl}`);

3. .env文件格式错误

.env里不要加引号和分号,正确格式是:

JWT_SECRET=Chaleya
NODE_ENV=production

把这些修改完之后,再测试一下authUser和getUserProfile接口,应该就能正常工作了!

备注:内容来源于stack exchange,提问作者Radical Rosh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 03:18:17