panva / openid-client

OAuth 2 / OpenID Connect Client API for JavaScript Runtimes
MIT License
1.83k stars 392 forks source link

Passport Strategy not return req.user #183

Closed xellDart closed 5 years ago

xellDart commented 5 years ago

Hi, I use lasted version with nodeJS 12.0

Here is my code:

Endpoints:

this.get('/login/openid', passport.authenticate('openid'));

this.post('/login/openid/callback',
    passport.authenticate('openid', {
        successRedirect: '/',
        failureRedirect: '/signup'
    })
);

Strategy:

let remIssuer = await Issuer.discover('http://127.0.0.1:3020/.well-known/openid-configuration');
const options = {
    client: new remIssuer.Client({
        client_id: 'doex_on_rem',
        response_types: ['token id_token'],
    }),
    params: config.passport.openid
};
const verify = (tokenSet, profile, done) => {

};
passport.use('openid', new Strategy(options, verify));

Config:

openid: {
    scope: 'openid email profile wallet',
    response_mode: 'form_post',
    nonce: 'doex_rem',
    passReqToCallback: true
}

I need get req.user on verify function, how i can get this param?

const verify = (req, tokenSet, profile, done) => {
    if (req.user) <= === = How to get this value ?
};
panva commented 5 years ago

Please be so kind and edit your description to a readable state first.

xellDart commented 5 years ago

Please be so kind and edit your description to a readable state first.

Im sorry, I already up this

big-kahuna-burger commented 5 years ago

@xperiafan13-rom You don't get it there. You set it there for the next middlewares in the chain. Take the subject and pass it to your db adapter to find matching user.

Like:

(req, userinfo, done) => {
  const user = await Users.findOne(userinfo.sub);
  if(!user) return done(new Error('user not found in db!'));
  return done(null, user);
}

Calling done with error will call strategy.fail and calling done with (null, someObject, someMoreInfo) will call strategy.success and set user. You need to consult passport docs on how this works, but this strategy implements it here

xellDart commented 5 years ago

But i need to load req.user on every request, in other strategies like twitter or google (and local) I use this:

if (req.user) {
                let token = await Services.redis.setSocketToken(req.user);
                return done(null, getUser(req.user, token));
} esle .... other logic

But withi this lib I cant get this param I already add passReqToCallback option to true (Association in Verify Callback)

big-kahuna-burger commented 5 years ago

That is not a issue of this library. Read passport js docs. Especially the part with serialize and deserialize user.

xellDart commented 5 years ago

I already have this

assport.serializeUser(function (user, done) {
    done(null, user);
});
passport.deserializeUser(function (uid, done) {
    done(null, uid);
});

and

let sessionMiddleware = session({
    store: new redisStore({host: config.redis.host, port: config.redis.port}),
    secret: config.session.key
});
big-kahuna-burger commented 5 years ago

If you could set up repo with a reproducible example, I might help you.

panva commented 5 years ago

I'm reading http://www.passportjs.org/docs/authorize, i checked the underlying twitter strategy and there's nothing this library's strategy isn't doing that twitter would be.

You need to correctly handle building the profile from the tokenset or userinfo response as step one and then adding passport.authorize call the same way you have probably have it for twitter or google.

You currently apply passport.authenticate instead.