Je réalise une application Web en utilisant nodejs et angular cli J'utilise JWT pour authentifier ma fonction de connexion. Mais quand je traite cela jeta cette erreur
Erreur: "charge utile" attendue comme objet simple . lors de la validation (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 [en tant que signe] (D:\Mean_Projects\meanauthapp\node_modules\jsonwebtoken\sign.js: 108: 7) sur 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 dans D:\Mean_Projects\meanauthapp\node_modules\bcryptjs\dist\bcrypt.js: 1353: 21 sur 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) à processImmediate [as _immediateCallback] (timers.js: 718: 5)
Voici mon code de passeport
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);
}
});
}));
}
Mon code pour s'authentifier et se profiler
// 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});
});
Il échoue à la ligne
const token = jwt.sign(user, config.secret, {
Avec erreur "La charge" attendue "est un objet"
Votre objet user
est initialisé ici:
User.getUserByUsername(username, (err, user)
Ce qui, je suppose, est un objet mongoosejs
, qui contient de nombreuses méthodes et n’est pas "sérialisable". Vous pouvez gérer cela en passant un objet brut, soit en utilisant la méthode .lean()
de mongoose
ou plain toJSON
:
const token = jwt.sign(user.toJSON(), config.secret, {
expiresIn: 604800 // 1 week
});
J'ai eu ce problème aussi, avec un utilisateur renvoyé de mangouste, il suffit d'ajouter toJSON()
ou toObject()
pour résoudre le problème, mais que se passe-t-il si votre utilisateur ne vient pas toujours de mangouste?
Vous obtiendrez un
user.toJson/user.ToObject n'est pas une fonction
si vous essayez de faire cela sur un objet simple.
Si votre utilisateur provient de sources différentes et que vous ne savez pas s'il s'agira d'un objet simple ou non, vous pouvez le résoudre comme suit:
JSON.parse(JSON.stringify(user));
ceci est clairement mentionné dans le document de migration de passport-jwt
qu'ils ont supprimé la ExtractJwt.fromAuthHeader()
des versions 2 et 3 et qu'ils utilisent également la nouvelle méthode ExtractJwt.fromAuthHeaderAsBearerToken()
ou une méthode similaire à la place de l'ancienne méthode. pour référence compelte visite
De votre journal, il y a le problème
User.comparePassword (D:\Mean_Projects\meanauthapp\routes\users.js:86:27) at
alors voici quatre choses doivent être mises à jour dans votre code @every Bit
D'abord dans le fichier package.json
Modifiez la version la plus récente en utilisant * ou la version n ° comme celle-ci.
npm install passport-jwt --save
"dependencies": {
....
"passport-jwt": "^3.0.1"
}
ou écrivez dans le fichier et exécutez la commadn
`npm install`
"dependencies": {
....
"passport-jwt": "*"
}
Deuxième changement de cette ligne de votre code dans la méthode authentifier
const token = jwt.sign(user.toJSON(), config.secret, {
expiresIn: 604800 // 1 week
});
Troisième dans le code de passeport changer l'ancienne méthode
ExtractJwt.fromAuthHeader();
pour en ajouter un nouveau, à partir de la référence de la documentation, vous devez utiliser cette méthode opts.jwtFromRequest=ExtractJwt.fromAuthHeaderWithScheme('jwt');
et quatrième changement cela
User.getUserById(jwt_payload._id,(err,user)=>{
Cette solution fonctionnera avec la dernière version
changez seulement la version de votre passport-jwt dans package.json en 1.x.x (x est le numéro ici) de votre choix de version inférieure puis 2,
en passant au dossier du projet et en exécutant la commande npm install
la seule chose à vérifier est les données dans payload_jwt, elles se trouveront dans la deuxième couche, veuillez donc vérifier jwt_payload.
ok vous êtes prêt à partir, vous avez déjà manipulé User.getUserById(jwt_payload._doc._id,(err,user)=>{
C'est très simple, si l'utilisateur vient de la base de données (mongo), il suffit simplement de faire user.toJSON()
, si l'utilisateur provient d'une autre source, il suffit simplement de faire JSON.stringify(user)
.