NodeJS 在同一应用程序上使用Passport Local和JWT策略(在同一路线上)

vybvopom  于 2023-04-29  发布在  Node.js
关注(0)|答案(2)|浏览(140)

所以我的**路由('/dash')**看起来像这样:

// validating using JWT
router.post('/dash', passport.authenticate('jwt', {session: false}), function (req, res) {
    res.json({'success': true});
});

// validating using LOCAL
router.post('/dash', authenticationHelpers.isAuth, function (req, res) {
    res.json({'success': true});
});

// authenticationHelpers.isAuth
function isAuth(req, res, next) {
    if (req.isAuthenticated())
        return next();
    res.status(401).json({"authenticated": false});
}

那么,我如何在同一个应用程序上(在同一条路线上)同时使用本地和JWT策略?如何将两者结合起来。

  • 注意:本地适用于Web应用,JWT适用于移动的应用 *
j91ykkif

j91ykkif1#

终于想通了。
修改的isAuth函数:

function isAuth(req, res, next) {
    if (req.headers.authorization) {
        passport.authenticate('jwt', {session: false}, function (err, user, info) {
            if ((!err || !info) && user) {
                req.user = user;
                return next();
            }
            res.status(401).json({authenticated: false, message: "Login expired."});
        })(req, res, next);
    } else {
        if (req.isAuthenticated())
            return next();
        res.status(401).json({authenticated: false});
    }
}

欢迎提出建议。..

wwtsj6pe

wwtsj6pe2#

我需要我的应用程序同样的事情,我不想单独的前端和后端,我想使用我的代码与 Postman 没有会话太多。所以我解决这样的问题
首先,我改变了我的“jwtFromRequest”,所以我可以寻找jwt从头部和sesssion在一起

const opts = {};
opts.jwtFromRequest = ExtractJwt.fromExtractors([
    ExtractJwt.fromAuthHeaderAsBearerToken(),
    (req) => req.session?.jwt || ''
]);

opts.secretOrKey = process.env.APP_SECRET;

module.exports = function (passport) {
    passport.use(
        new JwtStrategy(opts, (jwtPayload, done) => {

我定义了我的登录根(我有2根)

router.post(
    'auth/login',
    passport.authenticate('local', {
        failureRedirect: '/auth/login',
        failureFlash: true
    }),
    asyncHandler(AuthenticationController.login)
);

router.post(
    'api/login',
    [body('email').isEmail(), body('password').isLength({ min: 1 })],
    asyncHandler(AuthenticationController.loginJwt)
);

我在Controller的登录功能:

login: async (req, res, next) => {
    const jwtToken = req.user.generateJwt();
    req.session.jwt = jwtToken;
    res.redirect('/');
},
loginJwt: async (req, res) => {
    const lowerMail = (req.body.email || '').toLowerCase();
    const user = await User.findOne({ email: lowerMail })

    if (!user || !(await user.isValidPassword(req.body.password))) {
        return res.status(401).json(errRes(__l('auth.emailAndPasswordDoNotMatch')));
    }

    const token = user.generateJwt();

    return res.json(
        stdRes(__l('auth.successfullyLoggedIn'), {
            user: {
                _id: user._id,
                name: user.name,
                email: user.email
            },
            access_token: token
        })
    );
},

最后是我的检查认证中间件

function checkAuth(req, res, next) {
    passport.authenticate('jwt', (err, user) => {
        if (err) return next(err);
        if (!user) {
            if (req.xhr || req.headers.accept.indexOf('json') > -1) {
                return res.status(401).json(errRes(__l('auth.userIsNotAuthenticated')));
            }
            return res.redirect('/auth/login');
        }
        req.user = user;
        return next();
    })(req, res, next);
}
router.get('/', [checkAuth], DashboardController.homePage);

相关问题