我是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~
答案 0 :(得分:3)
我认为问题在于,当使用jwt.decode同时还有一个密钥时,你需要将一个选项传递给解码调用,并将complete设置为true:
来自jwt docs:
Device.dll
https://github.com/auth0/node-jsonwebtoken
显然最好在这里使用jwt.verify:
// 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)
答案 1 :(得分:2)
如果您正在使用此,
var decoded = jwt.decode(token, {complete: true});
or
var payload = jwt.decode(token);
检查令牌是否与此类似-> Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJ6YWNrIiwiaWF0IjoxNDU5MDAzMTYxfQ.rhqOX0ICRvivNCwwLNsu5KizNPLQTKPVEqfCuxtII90~
然后,在将令牌令牌传递给jwt.decode之前,我们必须从令牌中删除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);
答案 2 :(得分:0)
我也遇到了这个问题,最终我需要在令牌周围抛出JSON.parse()...
var decoded = jwt.decode(JSON.parse(token))