我正在使用nodejs和angular cli创建一个Web应用程序 我正在使用JWT来验证我的登录功能。但是当我处理它时抛出了这个错误
错误:期望“有效负载”成为普通对象。 在验证时(D:\ Mean_Projects \ meanauthapp \ node_modules \ jsonwebtoken \ sign.js:34:11) 在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) 在User.comparePassword(D:\ Mean_Projects \ meanauthapp \ routes \ users.js:86:27) 在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 在Immediate.next [as _onImmediate](D:\ Mean_Projects \ meanauthapp \ node_modules \ bcryptjs \ dist \ bcrypt.js:1233:21) 在runCallback(timers.js:785:20) 在tryOnImmediate(timers.js:747:5) at processImmediate [as _immediateCallback](timers.js:718:5)
这是我的护照代码
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);
}
});
}));
}
我的身份验证和获取个人资料的代码
// 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});
});
答案 0 :(得分:75)
它在
行失败了const token = jwt.sign(user, config.secret, {
错误“预期”有效负载“将成为普通对象”
您的user
对象在此处初始化:
User.getUserByUsername(username, (err, user)
我假设它是mongoosejs
对象,它包含许多方法并且不是“可序列化的”。您可以通过传递普通对象来处理此问题,方法是使用.lean()
中的mongoose
或普通toJSON
方法:
const token = jwt.sign(user.toJSON(), config.secret, {
expiresIn: 604800 // 1 week
});
答案 1 :(得分:13)
我也有这个问题,来自mongoose的返回用户,只需添加toJSON()
或toObject()
即可解决问题,但如果您的用户并非总是来自mongoose会怎样?
你会得到一个
user.toJson / user.ToObject不是函数
如果您尝试在普通对象上执行此操作。
如果您的用户来自不同的来源并且您不知道它是否是普通对象,您可以这样解决:
JSON.parse(JSON.stringify(user));
答案 2 :(得分:3)
他们已从版本2和3中删除ExtractJwt.fromAuthHeader()
,并使用新方法ExtractJwt.fromAuthHeaderAsBearerToken()
或类似的方法代替旧方法。 for compelte reference visit
从日志中出现问题
User.comparePassword (D:\Mean_Projects\meanauthapp\routes\users.js:86:27) at
所以这里需要在代码@every Bit
首先在package.json文件中
使用*或版本号将版本更改为最新版本
通过转到项目目录并运行命令
npm install passport-jwt --save
"dependencies": {
....
"passport-jwt": "^3.0.1"
}
或 写入文件并运行commadn
`npm install`
"dependencies": {
....
"passport-jwt": "*"
}
在验证方法
中再次更改此代码行const token = jwt.sign(user.toJSON(), config.secret, {
expiresIn: 604800 // 1 week
});
护照代码中的第三个更改旧方法
ExtractJwt.fromAuthHeader();
到新文档,您需要使用此方法opts.jwtFromRequest=ExtractJwt.fromAuthHeaderWithScheme('jwt');
并且第四次更改
User.getUserById(jwt_payload._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)=>{
答案 3 :(得分:1)
如果不是从月光来的 然后使用传播算子
const token = jwt.sign({ ...payload }, config.secret, {
expiresIn: 100080
});
答案 4 :(得分:0)
这非常简单,如果用户来自数据库(mongo),则只需执行user.toJSON()
,如果用户来自任何其他来源,则只需执行JSON.stringify(user)
。
答案 5 :(得分:0)
更改
const token = jwt.sign(user, config.secret, { expiresIn: 10080 });
收件人
const token = jwt.sign(user.toJSON(), config.secret, { expiresIn: 10080 });
答案 6 :(得分:0)
function utf8ize($mixed) {
if (is_array($mixed)) {
foreach ($mixed as $key => $value) {
$mixed[$key] = utf8ize($value);
}
} else if (is_string ($mixed)) {
return utf8_encode($mixed);
} else if (is_object($mixed)) {
$a = (array)$mixed; // from object to array
return utf8ize($a);
}
return $mixed;
}
将其转换为
const token = jwt.sign(user, config.secret, {
expiresIn: 604800 // 1 week
});
或者您需要console.log(jwt_payload);查找您的ID位于_doc下或直接与jwt_payload在一起。因为这可能会随版本而改变。