2016-03-26 6 views
4

Я новичок в Node.js, читая Node.js Essentials от Fabian Cook. При попытке кода при аутентификации с помощью JWT я получил NULL из jwt.decode (токен), но токен может быть проанализирован отладчиком на jwt.io. Что не так с кодом?JWT decode возвращает null

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 в то же время имея секретного ключа, вам нужно будет пройти в качестве опции для декодирования вызова с полным набором к истине:

От 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. 
+0

Привет @Omarjmh, я попытался использовать {compete: true} с jwt.decode(), но все равно не повезло. Я изменил код с более простым секретом и просто использовал jwt.verify(), и я получил еще одну ошибку, которая говорит, что токен недействителен. Но когда я распечатываю токен, он один и тот же: 'JsonWebTokenError: недопустимый токен в Object.JWT.verify (/Users/zacharychim/Documents/node/authentication/nodejs-passport/node_modules/jsonwebtoken/index.js: 201: 17) ' – Zack

+0

Вот новый код jwt.sign: ' вар маркер = jwt.sign (полезная нагрузка, 'MySecret'); ' И для jwt.verify: ' вар verifyToken = функция (маркер, done) { console.log (токен); jwt.verify (токен, 'mysecret', функция (ошибка, декодировано) { if (error || decoded == null) { return done (error, false); } return done (null, user); }) } ' – Zack

Смежные вопросы