JWT中间件如何获取Sequelize(MySQL)登录用户的完整数据
问题根因
现有JWT中间件仅将解码后的email字段挂载到req对象,未执行数据库查询挂载完整用户数据,因此控制器读取req.user时会得到空值。此前findByPK()调用失败通常是三个原因:JWT载荷未存储用户主键、异步查询未加await、方法名拼写错误/模型主键配置不匹配。
实现方案
- 改造JWT认证中间件,在token校验通过后查询对应用户数据,挂载到
req.user供后续控制器使用,查询时注意排除密码等敏感字段。
改造后的中间件代码如下,注意替换User模型的引入路径为你项目的实际路径:
import jwt from "jsonwebtoken"; // 替换为你项目中User Sequelize模型的实际存放路径 import User from "../models/User.js"; export const verifyToken = (req, res, next) => { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if(token == null) return res.sendStatus(401); jwt.verify(token, process.env.JWT_SECRET_KEY, async (err, decoded) => { if(err) return res.sendStatus(403); try { // 按邮箱匹配用户,排除敏感字段 const currentUser = await User.findOne({ where: { email: decoded.email }, attributes: { exclude: ['password', 'refreshToken'] } // 按需添加需要排除的敏感字段 }); if (!currentUser) return res.sendStatus(401); req.user = currentUser; next(); } catch (error) { return res.sendStatus(500); } }) }
- 确认路由配置,获取个人信息的接口必须在控制器前挂载
verifyToken中间件,参考配置:
import express from "express"; import { verifyToken } from "../middlewares/auth.js"; import { loggedUser } from "../controllers/user.js"; const userRouter = express.Router(); // 中间件顺序不能错,先鉴权查用户,再走控制器逻辑 userRouter.get("/api/user/profile", verifyToken, loggedUser); export default userRouter;
findByPk()使用注意事项:
如果你更倾向于用主键查询用户,需要先确认生成JWT时的载荷包含用户主键字段,示例生成token逻辑:
之后中间件里就可以替换查询逻辑为// 登录成功生成token时要把用户id存入payload const accessToken = jwt.sign( { id: user.id, email: user.email }, process.env.JWT_SECRET_KEY, { expiresIn: '1d' } );await User.findByPk(decoded.id, { attributes: { exclude: ['password'] } }),注意Sequelize的主键查询方法名是驼峰写法findByPk,如果写错成findByPK(末尾K大写)会直接报方法不存在的错误,这是调用失败的高频原因。
效果验证
前端请求个人信息接口时,在请求头携带格式为
Authorization: Bearer <登录拿到的token>的鉴权字段,接口就会返回排除敏感字段后的完整用户数据,可直接用于个人主页展示。
内容的提问来源于stack exchange,提问作者Velly Developers
相关产品推荐
相关产品推荐

