JWT 解码返回 null
Posted
技术标签:
【中文标题】JWT 解码返回 null【英文标题】:JWT decode returns null 【发布时间】:2016-07-14 05:26:56 【问题描述】:我是 Node.js 的新手,正在阅读 F*** 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~
【问题讨论】:
【参考方案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
是解决方案。以上是关于JWT 解码返回 null的主要内容,如果未能解决你的问题,请参考以下文章
Django GraphQL JWT:tokenAuth 突变返回“str 对象没有属性解码”
如何解码我在 Swift 中收到 REST API 的 JWT 令牌?