javascript jsonwebtoken 中的负载错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/47117709/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Payload error in jsonwebtoken
提问by every Bit
I am making a web application using nodejs and angular cli I'm using JWT to authenticate my login function . But when I process it threw this error
我正在使用 nodejs 和 angular cli 制作一个 Web 应用程序我正在使用 JWT 来验证我的登录功能。但是当我处理它时抛出了这个错误
Error: Expected "payload" to be a plain object. at validate (D:\Mean_Projects\meanauthapp\node_modules\jsonwebtoken\sign.js:34:11) at validatePayload (D:\Mean_Projects\meanauthapp\node_modules\jsonwebtoken\sign.js:56:10) at Object.module.exports [as sign] (D:\Mean_Projects\meanauthapp\node_modules\jsonwebtoken\sign.js:108:7) at User.comparePassword (D:\Mean_Projects\meanauthapp\routes\users.js:86:27) at bcrypt.compare (D:\Mean_Projects\meanauthapp\models\user.js:53:9) at D:\Mean_Projects\meanauthapp\node_modules\bcryptjs\dist\bcrypt.js:297:21 at D:\Mean_Projects\meanauthapp\node_modules\bcryptjs\dist\bcrypt.js:1353:21 at Immediate.next [as _onImmediate] (D:\Mean_Projects\meanauthapp\node_modules\bcryptjs\dist\bcrypt.js:1233:21) at runCallback (timers.js:785:20) at tryOnImmediate (timers.js:747:5) at processImmediate [as _immediateCallback] (timers.js:718:5)
错误:预期“有效负载”为普通对象。在验证 (D:\Mean_Projects\meanauthapp\node_modules\jsonwebtoken\sign.js:34:11) 在 validatePayload (D:\Mean_Projects\meanauthapp\node_modules\jsonwebtoken\sign.js:56:10) 在 Object.module.exports [as sign] (D:\Mean_Projects\meanauthapp\node_modules\jsonwebtoken\sign.js:108:7) at User.comparePassword (D:\Mean_Projects\meanauthapp\routes\users.js:86:27) at bcrypt.compare (D:\Mean_Projects\meanauthapp\models\user.js:53:9) 在 D:\Mean_Projects\meanauthapp\node_modules\bcryptjs\dist\bcrypt.js:297:21 在 D:\Mean_Projects\meanauthapp\node_modules\bcryptjs \dist\bcrypt.js:1353:21 at Immediate.next [as _onImmediate] (D:\Mean_Projects\meanauthapp\node_modules\bcryptjs\dist\bcrypt.js:1233:21) 在 runCallback (timers.js:785:
Here my passport code
这是我的护照代码
const JwtStrategy= require('passport-jwt').Strategy;
const ExtractJwt=require('passport-jwt').ExtractJwt;
const User= require('../models/user');
const config=require('../config/database');
module.exports=function(passport){
let opts={};
opts.jwtFromRequest=ExtractJwt.fromAuthHeader();
opts.secretOrKey=config.secret;
opts.issuer = 'accounts.examplesoft.com';
opts.audience = 'yoursite.net';
passport.use(new JwtStrategy(opts,(jwt_payload,done)=>{
console.log(jwt_payload);
User.getUserById(jwt_payload._doc._id,(err,user)=>{
if(err){
return done(err,false);
}
if(user){
return done(null,user);
}
else{
return done(null,false);
}
});
}));
}
My code for authenticate and get profile
我的身份验证和获取个人资料的代码
// Authenticate
router.post('/authenticate', (req, res, next) => {
const username = req.body.username;
const password = req.body.password;
User.getUserByUsername(username, (err, user) => {
if(err) throw err;
if(!user){
return res.json({success: false, msg: 'User not found'});
}
User.comparePassword(password, user.password, (err, isMatch) => {
if(err) throw err;
if(isMatch){
const token = jwt.sign(user, config.secret, {
expiresIn: 604800 // 1 week
});
res.json({
success: true,
token: 'JWT '+token,
user: {
id: user._id,
name: user.name,
username: user.username,
email: user.email
}
});
} else {
return res.json({success: false, msg: 'Wrong password'});
}
});
});
});
// Profile
router.get('/profile', passport.authenticate('jwt', {session:false}), (req, res, next) => {
res.json({user: req.user});
});
回答by Zilvinas
It fails at the line
它在线上失败
const token = jwt.sign(user, config.secret, {
With error "Expected "payload" to be a plain object"
错误“预期的“有效载荷”是一个普通对象”
Your userobject is initialized here:
您的user对象在此处初始化:
User.getUserByUsername(username, (err, user)
Which I assume is mongoosejsobject, which contains many methods and is not "serializable". You could handle this by passing a plain object, by either using .lean()from mongooseor plain toJSONmethod:
我假设是mongoosejs对象,它包含许多方法并且不是“可序列化的”。您可以通过使用.lean()frommongoose或普通toJSON方法传递普通对象来处理此问题:
const token = jwt.sign(user.toJSON(), config.secret, {
expiresIn: 604800 // 1 week
});
回答by Jose Agustin Villalobos Vargas
I had this problem as well, with a returned user from mongoose, just add toJSON()or toObject()will fix the issue, but what happens if your user is not always coming from mongoose?
我也遇到了这个问题,从猫鼬返回的用户,只需添加toJSON()或toObject()将解决问题,但如果您的用户并不总是来自猫鼬会发生什么?
You will get a
你会得到一个
user.toJson/user.ToObject is not a function
user.toJson/user.ToObject 不是函数
if you try to do this on a plain object.
如果您尝试在普通对象上执行此操作。
If your user is coming from different sources and you don't know if it will be a plain object or not, you can solve it like this:
如果您的用户来自不同的来源并且您不知道它是否是普通对象,您可以这样解决:
JSON.parse(JSON.stringify(user));
回答by Naval Kishor Jha
this is clearly mentioned in the migration doc of passport-jwt
这在passport-jwt的迁移文档中有明确提到
that they have removed the ExtractJwt.fromAuthHeader()from version 2 and 3 and also to use the new method ExtractJwt.fromAuthHeaderAsBearerToken()or one of like that in place of old method. for compelte reference visit
他们已经ExtractJwt.fromAuthHeader()从版本 2 和 3 中删除了,并且还使用新方法ExtractJwt.fromAuthHeaderAsBearerToken()或类似方法之一代替旧方法。完整的参考访问
From your log there is the issue
从你的日志有问题
User.comparePassword (D:\Mean_Projects\meanauthapp\routes\users.js:86:27) at
so here four thing need to be updated in your code @every Bit
所以这里有四件事需要在你的代码中更新 @every Bit
First in package.json file
Change the version to latest by using * or version no like this
by going to project directory and run the command
首先在 package.json 文件中
,使用 * 或 version no 将版本更改为最新版本,方法是转到项目目录并运行命令
npm install passport-jwt --save
"dependencies": {
....
"passport-jwt": "^3.0.1"
}
or write in the file and run the commadn
或写入文件并运行命令
`npm install`
"dependencies": {
....
"passport-jwt": "*"
}
Second change this line of your code in authenticate method
其次在身份验证方法中更改这行代码
const token = jwt.sign(user.toJSON(), config.secret, {
expiresIn: 604800 // 1 week
});
Third in the passport code change the old method
三在护照代码中改旧方法
ExtractJwt.fromAuthHeader();
to new one, from the doc reference you need to use this method opts.jwtFromRequest=ExtractJwt.fromAuthHeaderWithScheme('jwt');
到新的,从文档参考中,您需要使用此方法 opts.jwtFromRequest=ExtractJwt.fromAuthHeaderWithScheme('jwt');
and fourth change this
第四个改变这个
User.getUserById(jwt_payload._id,(err,user)=>{
This solution will work on latest version's
此解决方案适用于最新版本的
- if you still want to use this old method then
- 如果你仍然想使用这个旧方法那么
only change the version of your passport-jwt in package.json to 1.x.x (x is the nuber here )of your choise of lower version then 2,
by moving to project folder and runing the command npm install
the only thing you need to check is data in the payload_jwt,it will be inside the second layer so please check the jwt_payload.
ok you are all set to go you had already handled User.getUserById(jwt_payload._doc._id,(err,user)=>{
只需将 package.json 中的 Passport-jwt 版本更改为 1.xx(x 是此处的 nuber),然后选择较低版本的 2,
通过移动到项目文件夹并运行命令npm install
,您唯一需要检查的是数据在payload_jwt,它会在第二层,所以请检查jwt_payload。
好的,你已经准备好了,你已经处理了 User.getUserById(jwt_payload._doc._id,(err,user)=>{
回答by Naved Ahmad
It's very simple, if the user comes from database (mongo) then simply do user.toJSON(), if the user comes from any other source then simply do JSON.stringify(user).
这很简单,如果用户来自数据库(mongo),则只需执行user.toJSON(),如果用户来自任何其他来源,则只需执行JSON.stringify(user)。
回答by vijay
Change
改变
const token = jwt.sign(user, config.secret, { expiresIn: 10080 });
To
到
const token = jwt.sign(user.toJSON(), config.secret, { expiresIn: 10080 });
回答by Sujeewa K. Abeysinghe
const token = jwt.sign(user, config.secret, {
expiresIn: 604800 // 1 week
});
convert this to
将此转换为
const token = jwt.sign(user.toJSON(), config.secret, {
expiresIn: 604800 // 1 week
});
or you need to console.log(jwt_payload); to find your ID comes under _doc or directly with jwt_payload. because this may change with the versions.
或者你需要 console.log(jwt_payload); 查找您的 ID 位于 _doc 下或直接使用 jwt_payload。因为这可能会随着版本而改变。
回答by vijay
if it's not comming from moongose then use spread operator
如果它不是来自moongose,则使用扩展运算符
const token = jwt.sign({ ...payload }, config.secret, {
expiresIn: 100080
});

