Express项目调用jwtUtils.getUserId报not a function错误排查
JWT模块调用getUserId报"不是函数"问题排查
问题场景
开发认证模块时,使用Auth.js管理JWT认证令牌的生成、解析逻辑,文件内封装了getUserId方法,但在User控制器中引入该模块后调用该方法失败,系统提示方法不存在。
相关业务代码
userCtrl控制器调用代码
exports.getUserProfile = (req, res) => { let headerAuth = req.headers['authorization']; let userId = jwtUtils.getUserId(headerAuth); if (userId < 0) return res.status(400).json({ 'error': 'wrong token' }); models.User.findOne({ attributes: ['id', 'email', 'username', 'bio'], where: { id: userId } }).then((user) => { if (user) { res.status(201).json(user); } else { res.status(404).json({ 'error': 'user not found' }); } }).catch((err) => { res.status(500).json({ 'error': 'cannot fetch user' }); }); }
Auth.js工具模块原代码
let jwt = require('jsonwebtoken') const dotenv = require("dotenv") dotenv.config(); const JWT_SIGN_SECRET = process.env.JWT_SIGN_SECRET module.exports = { generateTokenForUser: (userdata) => { return jwt.sign({ userId: userdata.userId, isAdmin: userdata.isAdmin }, JWT_SIGN_SECRET, { expiresIn: '1h' }) } }, parseAuthorization = (authorization) => { return (authorization != nuill) ? authorization.replace('bearer', '') : null; }, getUserId = (authorization) => { let userId = -1; let token = module.exports.parseAuthorization(authorization); if (token != null) { try { let jwtToken = jwt.verify(token, JWT_SIGN_SECRET); if (jwtToken != null) userId = jwtToken.userId; } catch (err) { } } return userId; }
运行报错信息
TypeError: jwtUtils.getUserId is not a function at Route.dispatch (C:\Users\jorda\Desktop\P7\P7\Back\node_modules\express\lib\router\route.js:114:3) at Layer.handle [as handle_request] (C:\Users\jorda\Desktop\P7\P7\Back\node_modules\express\lib\router\layer.js:95:5) at C:\Users\jorda\Desktop\P7\P7\Back\node_modules\express\lib\router\index.js:284:15 at Function.process_params (C:\Users\jorda\Desktop\P7\P7\Back\node_modules\express\lib\router\index.js:346:12) at next (C:\Users\jorda\Desktop\P7\P7\Back\node_modules\express\lib\router\index.js:280:10) at Function.handle (C:\Users\jorda\Desktop\P7\P7\Back\node_modules\express\lib\router\index.js:175:3) at router (C:\Users\jorda\Desktop\P7\P7\Back\node_modules\express\lib\router\index.js:47:12)
问题原因
- 核心导出语法错误:
module.exports的对象在generateTokenForUser方法后就提前闭合了,后面的parseAuthorization、getUserId只是模块内的局部变量,没有被挂载到导出对象上,外部引入的jwtUtils对象上根本不存在这两个方法,调用自然报错。 - 拼写错误:
parseAuthorization方法中的判断条件将null错写为nuill,即使修复导出问题,运行到这里也会触发引用错误。 - 解析逻辑瑕疵:原代码替换
bearer字符串时没有处理标准头格式的空格、大小写问题,解析出的token会携带多余空格,导致后续JWT校验失败。
修复方案
调整Auth.js的导出结构,把三个方法都放到导出对象内,修正拼写错误,优化token解析逻辑,修复后的代码如下:
let jwt = require('jsonwebtoken') const dotenv = require("dotenv") dotenv.config(); const JWT_SIGN_SECRET = process.env.JWT_SIGN_SECRET module.exports = { generateTokenForUser: (userdata) => { return jwt.sign({ userId: userdata.userId, isAdmin: userdata.isAdmin }, JWT_SIGN_SECRET, { expiresIn: '1h' }) }, parseAuthorization: (authorization) => { return (authorization != null) ? authorization.replace(/^Bearer\s+/i, '').trim() : null; }, getUserId: (authorization) => { let userId = -1; let token = module.exports.parseAuthorization(authorization); if (token != null) { try { let jwtToken = jwt.verify(token, JWT_SIGN_SECRET); if (jwtToken != null) userId = jwtToken.userId; } catch (err) { } } return userId; } }
替换后重启服务即可正常调用。
内容的提问来源于stack exchange,提问作者Le Renard
相关产品推荐
相关产品推荐

