Search code examples
node.jstypescriptpassport.jspassport-local

Passport authenticate callback not being called


I had a problem with Passport's authenticate method. The callback supplied to the method was not called.

The code was as follows:

import { Router, Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
import passport from 'passport';

// ... some stuff

router.post('/login',
  (req: Request, res: Response, next: NextFunction) => {
    passport.authenticate('local', { session: false }, (err, user, info) => {

      // not reaching this part

      if (err) {
        return next(err);
      }

      if (err || !user) {
        return res.status(400).json({
          message: info ? info.message : 'Login failed',
          user,
        });
      }

      req.login(user, { session: false }, loginErr => {
        if (loginErr) {
          res.send(loginErr);
        }

        const token = jwt.sign(user, secrets.secret);

        return res.json({ user, token });
      });

      return res.status(500).send('Shouldn\'t come here');
    });
  },
  (err: any, req: Request, res: Response, next: NextFunction) => {
    return res.status(err.status || 500).send(err.message)
  });

Solution

  • I missed a crucial part of the example I based my code on. I had to use passport.authenticate as middleware. So, I used passport.authenticate to generate a function and then passed req, res and next to it like so:

    router.post('/login',
      (req: Request, res: Response, next: NextFunction) => {
    
        // vvv THIS VARIABLE
        const middleware = passport.authenticate('local', { session: false }, (err, user, info) => {
          if (err) {
            return next(err);
          }
    
          if (err || !user) {
            return res.status(400).json({
              message: info ? info.message : 'Login failed',
              user,
            });
          }
    
          req.login(user, { session: false }, loginErr => {
            if (loginErr) {
              res.send(loginErr);
            }
    
            const token = jwt.sign(user, secrets.secret);
    
            return res.json({ user, token });
          });
    
          return res.status(500).send('Shouldn\'t come here');
        });
    
       // vvv AND THIS FUNCTION CALL
        middleware(req, res, next);
      },
      (err: any, req: Request, res: Response, next: NextFunction) => {
        return res.status(err.status || 500).send(err.message)
      });
    

    And everything worked.