1

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.

ArchNoob
  • 3,946
  • 5
  • 32
  • 59
  • I don't think `const res = await ctx.response;` & `const req = await ctx.request;` is right because this expects the request and response objects in context to be promises yet to be executed, but I don't think that's the case, is it? – Ovidiu Dolha Jan 09 '17 at 11:41
  • @OvidiuDolha no it's not, i tried in the normal way (without `awaits`) around but that didn't work either. Lemme fix the code. – ArchNoob Jan 09 '17 at 11:55

2 Answers2

0

With koa passport, to access the authenticated user in other routes/middleware use ctx.state.user:

app.use(async ctx => { 
  ctx.state.user;
})

From koa passport readme and search for state.user

Paul Thompson
  • 1,071
  • 1
  • 8
  • 6
-1

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.

ArchNoob
  • 3,946
  • 5
  • 32
  • 59
  • 1
    The correct way to do this is to searialize and deserialize the user to the request, looks at https://stackoverflow.com/questions/27637609/understanding-passport-serialize-deserialize.. – adrien Jan 05 '19 at 13:34
  • @A__ Hello, I think I didn't use serializing/deserializing because I was using JWTs and not sessions. But that definitely looks like the correct way to do it. Thanks for the comment! – ArchNoob Jan 08 '19 at 08:31