express-jwt 将用户对象设置为 req.user._doc 而不仅仅是 req.user?
Posted
技术标签:
【中文标题】express-jwt 将用户对象设置为 req.user._doc 而不仅仅是 req.user?【英文标题】:express-jwt setting user object to req.user._doc instead of just req.user? 【发布时间】:2016-04-18 23:00:12 【问题描述】:我过去曾使用 npm 包 express-jwt 来轻松进行 JWT 签名、解码等。通常(和according to the docs)它会拦截请求,使用用户对象有效负载解码令牌并设置req.user
到那个有效载荷。然而,这一次它显示req.user
看起来像这样:
'$__':
strictMode: true,
getters: ,
wasPopulated: false,
activePaths: paths: [Object], states: [Object], stateNames: [Object] ,
emitter: domain: null, _events: , _maxListeners: 0 ,
isNew: false,
_doc:
__v: 0,
password: '$2a$10$ypbCbWsEA7W17IQjdox5Oe..MhhCco/0yIw.J1Y6m6vJDllCB0LLS',
username: 'b',
lastname: 'Last',
firstname: 'First',
_id: '56969210e3f8bf2ab9aee66d' ,
_pres: '$__original_save': [ null, null, null ] ,
_posts: '$__original_save': [] ,
iat: 1452709101
不仅仅是:
__v: 0,
password: '$2a$10$ypbCbWsEA7W17IQjdox5Oe..MhhCco/0yIw.J1Y6m6vJDllCB0LLS',
username: 'b',
lastname: 'Last',
firstname: 'First',
_id: '56969210e3f8bf2ab9aee66d'
我试图弄清楚为什么这一次我需要指定req.user._doc
来获取有关用户的具体信息。我已经比较了每个来源的代码,它实际上与过去的项目相同,我只是并排测试了它们 - 一个项目将 req.user 设置为用户对象,另一个将 req.user 设置为上面显示的对象,其中用户对象只能在_doc
属性中找到。
我检查了两个项目中 mongoose .findOne()
方法实际返回的内容,它是两个项目中上面显示的较大对象,但 express-jwt 似乎正在清除额外的对象在一个项目中自动填充,但在另一个项目中不自动填充。
我还注意到,包含我不想要的所有附加信息的 JWT 比项目中具有正确 req.user
对象的 JWT 长得多。所以也许这意味着当 JWT 使用有效负载签名时发生了一些奇怪的事情......
这是需要req.user._doc
的相关代码:
server.js
...
var expressJwt = require('express-jwt');
var authRoutes = require('./routes/authRoutes');
var nationRoutes = require('./routes/nationRoutes');
...
app.use('/api', expressJwt( secret: config.secret ));
app.use('/api/nation', nationRoutes);
app.use('/auth', authRoutes);
...
authRoutes.js
...
authRouter.post('/login', function (req, res)
User.findOne( username: req.body.username , function (err, user)
if (err) res.status(500).send(err);
if (!user) res.status(401).send('The username you entered does not exist');
else if (user)
bcrypt.compare(req.body.password, user.password, function (err, match)
if (err) throw (err);
if (!match) res.status(401).send("Incorrect Password");
else
var token = jwt.sign(user, config.secret);
res.send(
user: user,
token: token
);
);
);
);
...
nationRoutes.js(问题正在显现)
此时,express-jwt 已解码令牌并(假设)将令牌的有效负载(应该只是用户的信息,而不是额外的 $__
等内容)设置为 req.user
,但是我必须按照下面的代码所示执行req.user._doc
才能使其工作。
...
nationRouter.route('/')
.get(function (req, res)
console.log(req.user); // Shows the larger object with added stuff from above
Nation.find( user: req.user._doc._id , function (err, nations)
if (err)
res.status(500).send(err);
res.send(nations);
);
)
...
如果它有帮助,或者可能是问题的一部分,这里是用户模型和国家模型:
user.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var bcrypt = require("bcrypt");
var userSchema = new Schema(
firstname:
type: String,
required: true
,
lastname:
type: String,
required: true
,
username:
type: String,
required: true,
unique: true,
lowercase: true
,
password:
type: String,
required: true
,
email: String
);
userSchema.pre("save", function (next)
var user = this;
if (!user.isModified("password"))
next();
bcrypt.hash(user.password, 10, function (err, hash)
if (err) return next(err);
user.password = hash;
next();
);
);
module.exports = mongoose.model('User', userSchema);
nation.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Nation = new Schema(
name:
type: String,
required: true
,
creationDate:
type: Date,
default: Date.now
,
user:
type: Schema.Types.ObjectId,
ref: 'User'
);
module.exports = mongoose.model('Nation', Nation);
【问题讨论】:
你找到为什么会这样了吗? @amit,在下面查看我的更新答案,以及他们 github 问题页面上的对话链接。 【参考方案1】:我在我的代码中使用了 jsonewebtoken
包的过去版本号,并且问题在版本 5.5.1 中消失了。 (5.5.2好像已经引入了这个问题)。我查看了 jsonwebtoken 的源代码,并在他们的 github 问题页面(here 和 here)上与一些开发人员进行了几次对话。似乎他们在jwt.sign()
方法中向有效负载引入了一个名为xtend
的包,这似乎是在编码之前将所有额外的元属性添加到有效负载中。
我正在使用 Mongoose,根据其中一位 jsonwebtoken
开发人员的说法,我需要开始使用 Mongoose 的 Document.toObject()
方法。所以从现在开始:
...
jwt.sign(user.toObject(), ...)
...
将是在 Mongoose 中执行此操作的方式。
【讨论】:
以上是关于express-jwt 将用户对象设置为 req.user._doc 而不仅仅是 req.user?的主要内容,如果未能解决你的问题,请参考以下文章
express-jwt 无法从路由目录访问 req.user
受保护路由的 jest.mock express-jwt 中间件行为