web-dev-qa-db-ja.com

jsonwebtokenのペイロードエラー

Nodejsとangular cliを使用してWebアプリケーションを作成しています。JWTを使用してログイン機能を認証していますが、処理時にこのエラーがスローされました。

エラー:「ペイロード」はプレーンオブジェクトであると予想されました。検証時(D:\ Mean_Projects\meanauthapp\node_modules\jsonwebtoken\sign.js:34:11)検証時(D:\ Mean_Projects\meanauthapp\node_modules\jsonwebtoken\sign.js:56:10)at Object.module.exports [記号として](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、immediate.next [as _onImmediate](D:\ Mean_Projects\meanauthapp\node_modules\bcryptjs\dist\bcrypt.js:1233:21)at 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});
});
19
every Bit

ラインで失敗する

_const token = jwt.sign(user, config.secret, {
_

エラーあり""ペイロード "がプレーンオブジェクトであると予想されました"

userオブジェクトはここで初期化されます:

_User.getUserByUsername(username, (err, user)
_

私が推測するのはmongoosejsオブジェクトで、これには多くのメソッドが含まれており、「シリアライズ可能」ではありません。 mongooseからの.lean()またはプレーンtoJSONメソッドを使用して、プレーンオブジェクトを渡すことでこれを処理できます。

_const token = jwt.sign(user.toJSON(), config.secret, {
  expiresIn: 604800 // 1 week
});
_
85
Zilvinas

私もこの問題を抱えており、mongooseから返されたユーザーで、toJSON()またはtoObject()を追加するだけで問題が解決しますが、ユーザーが常にmongooseから来ていない場合はどうなりますか?

あなたは

user.toJson/user.ToObjectは関数ではありません

プレーンオブジェクトでこれを行おうとした場合。

ユーザーがさまざまなソースから来ており、それが単純なオブジェクトであるかどうかわからない場合は、次のように解決できます。

JSON.parse(JSON.stringify(user));

これは passport-jwtの移行ドキュメント で明確に言及されています

バージョン2および3からExtractJwt.fromAuthHeader()を削除し、古いメソッドの代わりに新しいメソッドExtractJwt.fromAuthHeaderAsBearerToken()またはそのようなメソッドを使用すること完全な参照用 visit

あなたのログから問題があります

_User.comparePassword (D:\Mean_Projects\meanauthapp\routes\users.js:86:27) at 
_

したがって、コードで4つのことを更新する必要があります_@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
});
_

パスポートコードの3番目は、古いメソッドを変更します

_ExtractJwt.fromAuthHeader();
_

新しいものにするには、ドキュメント参照からこのメソッドを使用する必要がありますopts.jwtFromRequest=ExtractJwt.fromAuthHeaderWithScheme('jwt');

そして4番目の変更

_User.getUserById(jwt_payload._id,(err,user)=>{
_

このソリューションは最新バージョンで動作します


  • それでもこの古い方法を使用したい場合は、


package.jsonのpassport-jwtのバージョンを1.x.xにのみ変更します(xはここでの数値です)下位バージョンの選択肢の2
プロジェクトフォルダーに移動し、コマンド_npm install_を実行する
確認する必要があるのは、payload_jwtのデータのみです。2番目のレイヤー内にあるため、jwt_payloadを確認してください。
OKあなたはすでにあなたがすでに処理したUser.getUserById(jwt_payload._doc._id,(err,user)=>{に行く準備ができています

3

ユーザーがデータベース(mongo)から来た場合はuser.toJSON()を実行し、他のソースから来た場合はJSON.stringify(user)を実行します。

1
Naved Ahmad