Reputation: 2318
so my route (for '/dash') looks like this:
// 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});
}
So, how do I use both Local & JWT Strategy on same app (on same route) ? How do I combine them both.
Note: Local for web app, JWT for mobile app
Upvotes: 2
Views: 968
Reputation: 117
I need same thing for my app, I dont want to separate frontend and backend and i want to use my codes with postman without session too. So i solve problem like this,
Firstly i changed my "jwtFromRequest", so i can look for jwt from header and sesssion together
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) => {
i defined my login root (i have 2 root)
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)
);
my login functions at 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
})
);
},
and lastly my middleware for check authentication
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);
Upvotes: 0
Reputation: 2318
Finally figured it out.
Modified isAuth function:
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});
}
}
Suggestions are welcomed...
Upvotes: 4