JWT认证报错:authenticate中间件后req.user始终为undefined
问题根因
两个核心写法错误导致认证失败、接口报错:
- 认证中间件
authenticate注册位置完全错误:你把中间件写在了控制器函数的参数列表里,Express框架根本不会执行这个中间件,自然不会给req.user赋值,所以打印永远是undefined。你写的exports.current = (authenticate, (req, res) => {})本质是自定义了一个接收两个参数的函数,第一个参数名刚好和你引入的authenticate重名,直接把引入的中间件变量遮蔽了,整个认证逻辑从来没有运行过。 - Knex查询链式调用被打断:你把
console.log(req.user)插在了knex('users')和.where()中间,JS换行不会自动延续链式调用,相当于单独执行.where()时前面没有调用主体,直接抛出Cannot read properties of undefined (reading 'where')错误。
修复方案
1. 修改路由文件,正确挂载认证中间件
Express的中间件需要在定义路由时按执行顺序传入路由方法,不要放在控制器里。修改currentRoute.js:
const router = require('express').Router(); const currentController = require('../controllers/currentController'); const authenticate = require('../middleware/authenticate'); // 路由层引入认证中间件 router .route('/') .get(authenticate, currentController.current); // 先执行认证,认证通过再进控制器 module.exports = router;
2. 修正控制器代码
移除控制器里错误的中间件参数,修复Knex链式调用,补充必要的错误处理,修改currentController.js:
const knex = require('knex')(require('../knexfile')); // [GET] /current 获取当前登录用户信息 exports.current = (req, res) => { console.log(req.user); // 这里可以正常打印解码后的token payload knex('users') .where({ email: req.user.email }) .first() .then((user) => { if (!user) { return res.status(404).send("用户不存在"); } delete user.password; res.json(user); }) .catch(err => { console.error(err); res.status(500).send("服务端错误"); }); };
额外校验点
改完后如果还有问题,确认两点:
- 登录/注册接口签发JWT时,payload里确实包含
email字段,否则req.user.email会是undefined导致查库失败 .env文件中配置的JWT_KEY和签发token时使用的密钥完全一致,否则JWT校验不通过会直接返回401
内容的提问来源于stack exchange,提问作者shmu305
相关产品推荐
相关产品推荐

