【问题标题】:JWT decode returns nullJWT 解码返回 null
【发布时间】:2016-07-14 05:26:56
【问题描述】:

我是 Node.js 的新手,正在阅读 Fabian Cook 的 Node.js Essentials。在尝试使用 JWT 进行身份验证时,我从 jwt.decode(token) 中得到了一个 NULL,但是 jwt.io 上的调试器可以解析该令牌。代码有什么问题?

var Passport = require( 'passport' );
var LocalStrategy = require( 'passport-local' ).Strategy;
var Express = require( 'express' );
var BodyParser = require( 'body-parser' );
var jwt = require( 'jsonwebtoken' );
var Crypto = require ( 'crypto' );

var users = {
  zack: {
    username: 'zack',
    password: '1234',
    id: 1,
  },
  node: {
    username: 'node',
    password: '5678',
    id: 2,
  },
}

var localStrategy = new LocalStrategy({
      usernameField: 'username',
      passwordField: 'password',
    },
    function(username, password, done) {
      user = users[ username ];

      if ( user == null ) {
        return done( null, false, { message: 'Invalid user' } );
      };

      if ( user.password !== password ) {
        return done( null, false, { message: 'Invalid password' } );
      };

      done( null, user );
    }
  )

Passport.use( 'local', localStrategy );

var app = Express();
app.use( BodyParser.urlencoded( { extended: false } ) );
app.use( BodyParser.json() );
app.use( Passport.initialize() );

var generateToken = function( req, res ) {
  var payload = {
    id: user.id,
    username: user.username
  }
  var secret = user.secret || Crypto.randomBytes( 128 ).toString( 'base64' );
  var token = jwt.sign( payload, secret );
  user.secret = secret;
  return token;
};

var generateTokenHandler = function ( req, res ) {
  var user = req.user;
  var token = generateToken( user );
  res.send( token );
};

app.post(
  '/login',
  Passport.authenticate( 'local', { session: false } ),
  generateTokenHandler
);

var BearerStrategy = require( 'passport-http-bearer' ).Strategy;

var verifyToken = function( token, done ) {
  var payload = jwt.decode(token);
  if ( payload == null ){
    return done( null, false );
  }
  console.log(payload);
  var user = users[ payload.username ];
  if ( user == null ||
       user.id !== payload.id ||
       user.username !== payload.username ) {
    return done( null, false );
  }
  jwt.verify( token, user.secret, function ( error, decoded ) {
    if ( error || decoded == null ) {
      return done( error, false );
    }
    return done( null, user );
  })
}
var bearerStrategy = new BearerStrategy( verifyToken )


Passport.use( 'bearer', bearerStrategy );


app.get(
  '/userinfo',
  Passport.authenticate( 'bearer', { session: false } ),
  function ( req, res ) {
    var user = request.user;
    res.send( {
      id: user.id,
      username: user.username
    });
  }
);

app.listen( 3000, function() {
  console.log( 'Listening on 3000' );
});

这是我从代码 F.Y.I. 中获得的令牌

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJ6YWNrIiwiaWF0IjoxNDU5MDAzMTYxfQ.rhqOX0ICRvivNCwwLNsu5KizNPLQTKPVEqfCuxtII90~

【问题讨论】:

    标签: javascript node.js jwt


    【解决方案1】:

    我认为问题在于,当使用 jwt.decode 同时还拥有密钥时,您需要将选项传递给解码调用,并将完整设置为 true:

    来自 jwt 文档:

    // get the decoded payload ignoring signature, no secretOrPrivateKey needed
    var decoded = jwt.decode(token);
    
    // get the decoded payload and header
    var decoded = jwt.decode(token, {complete: true});
    console.log(decoded.header);
    console.log(decoded.payload)
    

    https://github.com/auth0/node-jsonwebtoken

    显然最好在这里使用 jwt.verify:

    Warning: This will not verify whether the signature is valid. You should 
    not use this for untrusted messages. You most likely want to use jwt.verify instead.
    

    【讨论】:

    • 嗨@Omarjmh,我尝试将 {compete: true} 与 jwt.decode() 一起使用,但仍然没有运气。我用一个更简单的秘密更改了代码,只使用了 jwt.verify(),我得到了另一个错误,它说令牌无效。但是当我打印出令牌时,它是同一个:JsonWebTokenError: invalid token at Object.JWT.verify (/Users/zacharychim/Documents/node/authentication/nodejs-passport/node_modules/jsonwebtoken/index.js:201:17)
    • 这里是 jwt.sign 的新代码:var token = jwt.sign( payload, 'mysecret' ); jwt.verify:var verifyToken = function( token, done ) { console.log(token); jwt.verify( token, 'mysecret', function ( error, decoded ) { if ( error || decoded == null ) { return done( error, false ); } return done( null, user ); }) }
    【解决方案2】:

    如果你正在使用这个,

    var decoded = jwt.decode(token, {complete: true}); 
    or 
    var payload = jwt.decode(token);
    

    检查token是否与此类似-> Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJ6YWNrIiwiaWF0IjoxNDU5MDAzMTYxfQ.rhqOX0ICRvivNCwwLNsu5KizNPLQTKPVEqfCuxtII90~

    然后,在将令牌令牌传递给 jwt.decode 之前,我们必须从令牌中删除 Bearer,然后将其传递。 Bearer是一种授权类型,需要去掉。 例如:

    var newToken = token.substring(7, bearerString.length); // used to remove the Bearer string and space from the token so that it consists of only header,payload and signature.
    var decoded = jwt.decode(newToken, { complete: true });
    or 
    var payload = jwt.decode(newToken);
    

    【讨论】:

    • 我忘了删除“承载”。谢谢!
    【解决方案3】:

    我也遇到了这个问题,最后我需要在令牌周围抛出一个 JSON.parse()...

    var decoded = jwt.decode(JSON.parse(token))
    

    【讨论】:

    • 是的,JSON.parse 是解决方案。
    猜你喜欢
    • 2020-06-29
    • 2018-09-25
    • 2021-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多