Search code examples
asynchronouspassport.jskoakoa-routerkoa-passport

Koa 2 + Passport + async


Trying to implement a local Passport strategy in Koa 2 but I'm missing something vital...

When my route hits passport.authenticate(), I'm able to retrieve my user but I'm never returning from that await(), so my code doesn't progress any further.

auth:

passport.use( new LocalStrategy(async(username, password, done) => {
  console.log('AUTHENTICATING!');
  try {
     let user = await User.findOne({username:username});
    if(user) {
      console.log('USER FOUND - DONE');
      done(null, user);
    } else {
      console.log('USER NOT FOUND - DONE');
      done(null, false);
  }
  } catch (err) {
    throw err;
  }
}));

routes

router.post('/login', bodyParser(), async(ctx, next) => {
  try {
    await passport.authenticate('local')(ctx,next);
    console.log('I NEVER MAKE IT TO THIS POINT');
  } catch (err) {
    throw err;
  }
});

So my code hits ('USER FOUND - DONE')... but I never reach 'I NEVER MAKE IT TO THIS POINT' in the route. Have tried switching several things so I'm sure it could be something really silly I'm not doing right.


Solution

  • So my issue was that passport.authentincate() returns a good ol' callback and I was trying to use it as a promise.

    I wrapped the local strategy in a co() function and it's working:

    passport.use( new LocalStrategy('local', function(username, password, done) {
      return co(function*(){
        try {
          let user = yield Promise.resolve(User.findOne({username:username}));
          if(user) {
            console.log('USER FOUND - DONE');
            return done(null, user);
          } else {
            console.log('USER NOT FOUND - DONE');
            return done(null, false);
          }
        } catch (err) {
          throw err;
        }
      });
    }));
    

    I would love to know if there is any other way to accomplish this in full async / await fashion - I was hoping not to have to use co() for this.