Search code examples
javascriptnode.jspassport.jskoapassport-local

Koa v2, getting user object after passport-loca login


I'm failing to get user object to the next middleware after passport.authenticate('local', {session: false}) middleware passes successfully.

Here is how my code looks like.

In passport Local Strategy

passport.use(new localStrategy((username, password, done) => {

    User.findOne({username}, (err, user) => {
        
        if(err) { return done(err) }

        if(!user) { return done(err) }

        user.comparePasswords(password, async(err, isMatch) => {

            if(!isMatch) { return done(null, false) }

            done(null, user);
        });
    });
}));

which I think is suppose to return the user object if login is successfully made.

Then in my routes I have

const requireAuth = passport.authenticate('local', {session: false});

router.post('/login', requireAuth, signIn);

As when I hit /signin the passport middleware is called and then when it's done signIn middleware is called Something i'm expecting, with my logged in user object.

But when I check in my signIn middleware nothing is passed (In the request or response) object.

Here is my signIn middleware

const signIn = async (ctx, next) => {
    const res = ctx.response;
    const req = ctx.request;

    console.log('response', res); //- Nothing from passport
    console.log('request', req); //- Nothing from passport
    await next();
};

I need to pass the logged in user from passport to the next middleware so I can use the user Id to make a jwt.

Thank you.


Solution

  • I've got it to work with passReqToCallback i'm not sure if this is the proper way though, To override the request body but that's what got this app to work for now.

    Here is my passport.js file The only file that changned.

    passport.use(new localStrategy(
      {passReqToCallback: true},
      async(req, username, password, done) => {
    
        User.findOne({username}, (err, user) => {
            
            if(err) { return done(err) }
    
            if(!user) { return done(err) }
    
            user.comparePasswords(password, async(err, isMatch) => {
    
                if(!isMatch) { return done(null, false) }
    
                req.body = user;
                await done(null, user);
            });
        });
    }));

    Yeah i'm overriding my req.body with the user obtained from db.

    I honestly don't know why i still keep the done(null, user) i could as well just said done(null, true) but that's just me.

    If anyone has a better solution please post cause i'm not really feeling this code.

    Thanks.