护照验证 jwt 没有响应

Passport authenticate jwt not responding

我有一个基本的 MERN login/signup 应用程序,其中包含一条虚拟保护路由,仅对登录用户可见。我已经设置了与登录和注册相关的所有内容。 我在 cookie 中从服务器发送 jwt 令牌。到目前为止,aprt 工作正常。我可以注册,也可以登录。 但是当我对 /protected 路由进行 GET 调用时,passport.jwt 似乎不起作用。那里什么也没有发生。 这是我的 passport.js 配置:

import {Strategy} from 'passport-jwt';
// import {ExtractJwt} from 'passport-jwt';
import passport from 'passport';
import mongoose from 'mongoose';
import {UserSchema} from '../models/userModel';
import {config} from './config';

const User = mongoose.model('User', UserSchema);

const cookieExtractor = (req) => {
    let token = null;
    if(req && req.cookies) {
        token = req.cookies['jwt'];
    }
    return token;
}

export const passportConfig = (passport) => {
    const opts = {};
    opts.jwtFromRequest = cookieExtractor;
    opts.secretOrKey = config.key;
    passport.use(
        new Strategy(opts, (jwt_payload, done) => {
            User.findById(jwt_payload.id)
                .then((user) => {
                    if(user) {
                        return done(null, user);
                    }
                    return done(null, false);
                })
                .catch((err) => {
                    console.log('Error in finding user by id in jwt.');
                });
        })
    );
};

这里是 userRoutes.js:

import { addNewUser, loginUser, verifyLogin } from '../controllers/userController';

export const routes = (app) => {
    app.route('/users/register')
        .post(addNewUser);
    app.route('/users/login')
        .post(loginUser);
    app.route('/users/protected')
        .get(verifyLogin);
}

最后,这是我 userController.js 中的 verifyLoginloginUser 控制器:

export const loginUser = (req, res) => {
    console.log(req.body);
    if(mongoSanitize.has(req.body)) {
        return res.send(400).json({error: "Characters $ and . are prohibited. Use different values."});
    }

    const {errors, isValid} = validateLoginInput(req.body);
    if(!isValid) {
        return res.status(400).json(errors);
    }

    const userName = req.body.userName;
    const password = req.body.password;

    User.findOne({userName: userName})
        .then((user) => {
            if(!user) {
                return res.status(404).json({userNotFound: "Username not found."});
            }
            else {
                bcrypt.compare(password, user.password)
                    .then((isMatch) => {
                        if(isMatch) {
                            const payload = {
                                id: user.id,
                                name: user.fullName
                            };
                            const token = jwt.sign(payload, config.key, {expiresIn: 60});
                            res.cookie('jwt', token, {httpOnly: true, secure: false});
                            res.status(200).json({success: true, token: token});
                        }
                        else {
                            return res.status(400).json({incorrectPassword: "Password incorrect."});
                        }
                    })
            }
        });
};

export const verifyLogin = () => {
    console.log('protected'); //'protected' is printed
    passport.authenticate('jwt', {session: false}),
    (req, res) => {
        console.log('here'); //'here' is not printed
        const { user } = req;
        res.send(200).send({user});
    };
};

控制器 loginUser 工作正常,我可以看到响应中的令牌,而且我还有一个包含 jwt key:value 对的 cookie。 但是第三个控制器 verifyLoginpassport.authenticate 调用后没有做任何事情。

有什么地方我可能做错了什么吗?

好的,所以我能够修复。其他人有同样的问题,问题是我没有使用 passport.authenticate 作为中间件,而是我将它作为一个函数调用,并在成功验证时进行回调。以下是我所做的更改:

userRoutes.js:

export const routes = (app) => {
    app.route('/register')
        .post(addNewUser);
    app.route('/login')
        .post(loginUser);
    app.route('/protected')
        .get(passport.authenticate('jwt', {session:false}), verifyLogin);
}

然后verifyLogin只是将登录的用户信息发回:

export const verifyLogin = (req, res) => {
    console.log('here');
    const { user } = req;
    res.status(200).json({message:'Secure route', user: user});
};

其他都差不多。

在我将时间更改为 1 小时之前,我遇到了同样的问题。看起来你写的值是以毫秒为单位的,所以你应该写 60000.

而不是 60