Ich mache eine Webanwendung mit nodejs und angle cli Ich verwende JWT, um meine Login-Funktion zu authentifizieren. Aber wenn ich es verarbeite, warf es diesen Fehler
Fehler: Erwartete "Nutzlast" als einfaches Objekt . at validate (D:\Mean_Projects\meanauthapp\node_modules\jsonwebtoken\sign.js: 34: 11) bei validatePayload (D:\Mean_Projects\meanauthapp\node_modules\jsonwebtoken\sign.js: 56: 10) at Object.module.exports [als Zeichen] (D:\Mean_Projects\meanauthapp\node_modules\jsonwebtoken\sign.js: 108: 7) at User.comparePassword (D:\Mean_Projects\meanauthapp\routes\users.js: 86: 27) bei 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)
Hier mein Passcode
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);
}
});
}));
}
Mein Code zum Authentifizieren und Abrufen des Profils
// 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});
});
Es scheitert an der Leitung
const token = jwt.sign(user, config.secret, {
Mit Fehler "Erwartete" Nutzlast "ein einfaches Objekt"
Ihr user
-Objekt wird hier initialisiert:
User.getUserByUsername(username, (err, user)
Ich gehe davon aus, dass es sich um ein mongoosejs
-Objekt handelt, das viele Methoden enthält und nicht "serialisierbar" ist. Sie können dies umgehen, indem Sie ein einfaches Objekt übergeben, indem Sie entweder .lean()
von mongoose
oder die plain toJSON
-Methode verwenden:
const token = jwt.sign(user.toJSON(), config.secret, {
expiresIn: 604800 // 1 week
});
Ich hatte auch dieses Problem. Mit einem zurückgegebenen Benutzer von mongoose fügen Sie einfach toJSON()
hinzu oder toObject()
wird das Problem beheben. Was passiert jedoch, wenn Ihr Benutzer nicht immer von mongoose kommt?
Sie erhalten eine
user.toJson/user.ToObject ist keine Funktion
wenn Sie versuchen, dies an einem einfachen Objekt durchzuführen.
Wenn Ihr Benutzer aus verschiedenen Quellen kommt und Sie nicht wissen, ob es sich um ein einfaches Objekt handelt oder nicht, können Sie es wie folgt lösen:
JSON.parse(JSON.stringify(user));
dies ist eindeutig im migrationsdokument von passport-jwt erwähnt
dass sie ExtractJwt.fromAuthHeader()
von Version 2 und 3 entfernt haben und auch die neue Methode ExtractJwt.fromAuthHeaderAsBearerToken()
oder eine ähnliche Methode anstelle der alten Methode verwenden. für eine qualifizierte Referenz Besuch
In Ihrem Log gibt es das Problem
User.comparePassword (D:\Mean_Projects\meanauthapp\routes\users.js:86:27) at
hier müssen also vier Dinge in Ihrem Code aktualisiert werden @every Bit
Zuerst in der package.json-Datei
Ändern Sie die Version auf den neuesten Stand, indem Sie * oder Version no wie folgt verwenden Wechseln Sie zum Projektverzeichnis und führen Sie den Befehl aus
npm install passport-jwt --save
"dependencies": {
....
"passport-jwt": "^3.0.1"
}
oder Schreiben Sie in die Datei und führen Sie das Commadn aus
`npm install`
"dependencies": {
....
"passport-jwt": "*"
}
Zweitens ändern Sie diese Codezeile in der Authentifizierungsmethode
const token = jwt.sign(user.toJSON(), config.secret, {
expiresIn: 604800 // 1 week
});
Drittens im Passcode ändern Sie die alte Methode
ExtractJwt.fromAuthHeader();
um eine neue zu erstellen, müssen Sie aus der Dokumentenreferenz diese Methode verwenden. opts.jwtFromRequest=ExtractJwt.fromAuthHeaderWithScheme('jwt');
und viertens das ändern
User.getUserById(jwt_payload._id,(err,user)=>{
Diese Lösung funktioniert mit der neuesten Version
Ändern Sie nur die Version Ihres Passport-jwt in package.json in 1.x.x (x ist hier die Nummer) Ihrer Wahl der niedrigeren Version, dann 2,
indem Sie in den Projektordner wechseln und den Befehl npm install
.__ ausführen.
Sie müssen lediglich die Daten in der payload_jwt überprüfen. Diese Daten befinden sich in der zweiten Ebene. Überprüfen Sie daher die Option jwt_payload.
OK, Sie sind bereit zu gehen Sie haben bereits User.getUserById(jwt_payload._doc._id,(err,user)=>{
behandelt
Es ist sehr einfach, wenn der Benutzer aus einer Datenbank (Mongo) kommt, dann einfach user.toJSON()
, wenn der Benutzer aus einer anderen Quelle kommt, dann einfach JSON.stringify(user)
.