使用passport-jwt登录后未经授权

时间:2018-07-14 07:25:37

标签: node.js express authentication jwt passport-jwt


我用passport-jwt登录。它找到用户并且用户可以登录,但是登录后,我想重定向到用户仪表板,什么也没有发生,当它重定向到localhost:8080 / my /时,它在浏览器中显示未经授权 你能找出问题所在吗?

p.s:当我从my.js中删除passport.authenticate('jwt', {session: false})时,它可以工作,并且重定向到/ my /。所以我认为问题出在auth.js中的这部分代码或JWTStrategy。我不知道如何解决!

这是我的代码:(很抱歉,很多代码)

auth.js:

//Create a passport middleware to handle User login
passport.use(new LocalStrategy({
    usernameField: 'username',
    passwordField: 'password'
}, async (username, password, done) => {
    try {
        //Find the user associated with the email provided by the user
        await User.findOne({
            username: username
        }, async function (err, user) {
            if (!user) {
                //If the user isn't found in the database, return a message
                return done(null, false, {
                    message: 'User not found'
                });
            }
            //Validate password and make sure it matches with the corresponding hash stored in the database
            //If the passwords match, it returns a value of true.
            let validate = await user.isValidPassword(password);
            if (!validate) {
                return done(null, false, {
                    message: 'Wrong Password'
                });
            }
            //Send the user information to the next middleware
            return done(null, user, {
                message: 'Logged in Successfully'
            });
        });
    } catch (error) {
        return done(error);
    }
}));


passport.use(new JWTStrategy({
    jwtFromRequest : ExtractJWT.fromAuthHeaderAsBearerToken(),
    secretOrKey : 'secret_token'
}, function(jwt_payload, done) {
    User.findOne({id: jwt_payload.sub}, function(err, user) {
        if (err) {
            return done(err, false);
        }
        if (user) {
            return done(null, user);
        } else {
            return done(null, false);
            // or you could create a new account
        }
    });
}));

authenticate.js:

router.post('/login', async (req, res, next) => {
    passport.authenticate('local', async (err, user, info) => {
        try {

            if (err || !user) {
                const error = new Error('An Error occured')
                return next(error);
            }
            req.login(user, {
                session: false
            }, async (error) => {
                if (error) return next(error)
                //We don't want to store the sensitive information such as the
                //user password in the token so we pick only the email and id
                const body = {
                    _id: user._id,
                    username: user.username
                };
                //Sign the JWT token and populate the payload with the user email and id
                const token = jwt.sign({
                    user: body
                }, 'top_secret');
                //Send back the token to the user
                // return res.json({
                //     token
                // });
                res.redirect('/my/?token='+token);
            });
        } catch (error) {
            return next(error);
        }
    })(req, res, next);
});

module.exports = router;

user.js

const mongoose = require('mongoose');
const Role = require('./role');
const bcrypt = require('bcrypt');
let Schema = mongoose.Schema;
let userSchema = new Schema({
    .
    .
    .
});

userSchema.pre('save', async function(next){
    //'this' refers to the current document about to be saved
    const user = this;
    //Hash the password with a salt round of 10, the higher the rounds the more secure, but the slower
    //your application becomes.
    const hash = await bcrypt.hash(this.password, 10);
    //Replace the plain text password with the hash and then store it
    this.password = hash;
    //Indicates we're done and moves on to the next middleware
    next();
  });

  userSchema.methods.isValidPassword = async function(password){
    const user = this;
    //Hashes the password sent by the user for login and checks if the hashed password stored in the 
    //database matches the one sent. Returns true if it does else false.
    let compare= await bcrypt.compare(password , user.password);
    return compare;
  }

module.exports = mongoose.model('User' , userSchema);

my.js

//secure routes that only users with verified tokens can access.
//Lets say the route below is very sensitive and we want only authorized users to have access

//Displays information tailored according to the logged in user
router.get('/',passport.authenticate('jwt', {session: false}), (req, res) => {
    //We'll just send back the user details and the token
    res.json({
      message : 'You made it to the secure route',

      token : req.query.token
    });
  })



module.exports = router;

1 个答案:

答案 0 :(得分:0)

由于无效的JWT,通常会出现此问题。要使用passport-jwt对JWT进行身份验证,它必须采用以下格式:

"JWT xxxx.xxxx.xxxx"

因此,请尝试更改Authenticate.js文件中的以下行:

res.redirect('/my/?token='+token);
// CHANGE IT TO:
res.redirect('/my/?token=' + 'JWT ' + token);

我希望这可以解决您的问题。