0


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

ps:当我passport.authenticate('jwt', {session: false})从 my.js 中删除时,它可以工作并重定向到 /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
        }
    });
}));

验证.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;

用户.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);

我的.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;
4

1 回答 1

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);

我希望这能解决你的问题。

于 2018-07-15T04:12:30.713 回答