bob*_*byz 5 mongoose mongodb node.js express express-jwt
我过去使用过npm包express-jwt来进行简单的JWT签名,解码等.通常(根据文档)它拦截请求,用用户对象有效负载解码令牌并设置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
}
Run Code Online (Sandbox Code Playgroud)
而不仅仅是:
{
__v: 0,
password: '$2a$10$ypbCbWsEA7W17IQjdox5Oe..MhhCco/0yIw.J1Y6m6vJDllCB0LLS',
username: 'b',
lastname: 'Last',
firstname: 'First',
_id: '56969210e3f8bf2ab9aee66d'
}
Run Code Online (Sandbox Code Playgroud)
我想弄清楚为什么这次我需要指定req.user._doc以获取有关用户的具体信息.我在每个源代码都比较了我的代码,它几乎与过去的项目相同,我只是并排测试它们 - 一个项目将req.user设置为用户对象,另一个项目将req.user设置为上面显示的对象,用户对象只能在_doc属性中找到的位置.
我检查了.findOne()两个项目中实际从mongoose 方法返回的内容,并且它是上面两个项目中显示的较大对象,但是express-jwt似乎是在一个项目中自动清除多余的东西,而不是在另一个项目中.
我还注意到JWT具有我不想要的所有附加信息比使用正确req.user对象的项目中的JWT长得多.所以也许这意味着当JWT与有效载荷签约时会发生一些奇怪的事情......
以下是需要的相关代码req.user._doc:
...
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);
...
Run Code Online (Sandbox Code Playgroud)
...
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
});
}
});
}
});
});
...
Run Code Online (Sandbox Code Playgroud)
至此,快车智威汤逊已经解码的令牌和(据说)设置令牌的有效载荷(这应该只是用户的信息,而不是额外的$__,等东西)来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);
});
})
...
Run Code Online (Sandbox Code Playgroud)
如果它有用,或者可能是问题的一部分,这里是用户模型和国家模型:
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);
Run Code Online (Sandbox Code Playgroud)
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);
Run Code Online (Sandbox Code Playgroud)
我jsonewebtoken在我的代码中使用了包的过去版本号,问题随着版本5.5.1而消失.(5.5.2似乎已经引入了这个问题).我查看了jsonwebtoken的源代码,并在github问题页面(这里和这里)与一些开发人员进行了几次对话.看起来他们xtend在jwt.sign()方法中引入了一个名为有效负载的包,它似乎是在编码之前将所有额外的元属性添加到有效负载上.
我正在使用Mongoose,据其中一位jsonwebtoken开发人员说,我需要开始使用Document.toObject()Mongoose 的方法.所以从现在开始:
...
jwt.sign(user.toObject(), ...)
...
Run Code Online (Sandbox Code Playgroud)
将是在Mongoose中这样做的方法.
| 归档时间: |
|
| 查看次数: |
2532 次 |
| 最近记录: |