0
votes

Please take a look at this basic login/token process using passport basic strategy for a Rest API:

the route:

router.get('/token', authenticate.basic, controller.token);

authenticate basic strategy:

authenticate.basic = passport.authenticate('basic', {session: false});

/* implementation of the Basic Strategy*/
passport.use('basic', new BasicStrategy(function(username, password, done) {
    authenticationService.login(username, password).then(function(user) {
        if (!user) { 
              return done(null, false, { message: 'Login failed' }); 
        }
        return done(null, user);    
    }).catch(function(e) {
        return done(e)
    });
}));

token controller (route handler):

controller.token = function(req, res, next) {
    if (!req.user) {
        // TODO fix this dead branch 
        return res.json(401, {error: "Login failed"});
    }

    authService.issueToken(req.user).then(function(token) {

        var user = {
            user_id: req.user.id,
            access_token: token
        }           

        return res.json(user);

    }).catch(function(e) { 
        return next(e);
    });
};

As mentioned in the documentation :

By default, if authentication fails, Passport will respond with a 401 Unauthorized status, and any additional route handlers will not be invoked. If authentication succeeds, the next handler will be invoked and the req.user property will be set to the authenticated user.

Is there a way to bypass this behavior and invoke the route handler even if the authentication fails ?

1

1 Answers

0
votes

You're looking for Passport's "Custom callback" feature.

Basically, you need to give the authenticate method a third argument to override the default behavior. This implies that the application becomes responsible for logging in the user, which is simply a matter of calling the req.login() method.

authenticate.basic = function (req, res, next) {
  passport.authenticate('basic', {
    session: false
  }, function(err, user, info) {
    if (err) {
      // Authentication failed, you can look at the "info" object
      return next(err);
    }

    if (!user) {
      // The user is not logged in (no token or cookie)
      return res.redirect('/login');
    }

    req.login(user, function(err) {
      if (err) {
        // Something wrong happened while logging in, look at the err object
        return next(err);
      }

      // Everything's good!
      return res.redirect('/users/' + user.username);
    });
  })(req, res, next);
}