rkusa/koa-passport

No access to context in Strategy.

atassis opened this issue ยท 17 comments

Hello. When I try to get user data in strategy, I can't get the state data. For example, I need to authenticate user to tether his data of different socials, so in express I'ld need to set passReqToCallback: true in strategy.
For now I made a hack in my project- in file lib/framework/request.js I changed exports.create function to this:

  const req = Object.create(ctx.request, properties)

  // add passport http.IncomingMessage extensions
  req.login = IncomingMessageExt.logIn
  req.logIn = IncomingMessageExt.logIn
  req.logout = IncomingMessageExt.logOut
  req.logOut = IncomingMessageExt.logOut
  req.isAuthenticated = IncomingMessageExt.isAuthenticated
  req.isUnauthenticated = IncomingMessageExt.isUnauthenticated
  req.ctx = ctx;
  return req
}

Just added req.ctx=ctx; before return req so I can use ctx in my strategy.

rkusa commented

For compatibility reasons, the user object is also accessible from req.user. So you should be able to use passReqToCallback. Or do you need something else from the ctx?

@rkusa, For most circumstances, I really do need req.user only. But in some cases, I need to get some specific data from context. Anyway, my variant is not breaking passport behaviour. I am already using it with koa-passport-ot module and getting the ctx by destructuring req.

I pass the database connection through middlewares via ctx.state so having access to that in the strategy would be nice, for persistence.

rkusa commented

A workaround that does not break the compatibility with passport would be to add the context to the req object: req.ctx. However, I am not sure if I want to add this to koa-passport, because it is simple to implement this workaround on your own and I think most users don't need this functionality. What do you guys think?

I think passport is biased by express/connect, but having if not full ctx but at least the state would be beneficial.

rkusa commented

It definitely is biased by express/connect, which is really unfortunate. I've checked the source of passport and its strategies again. There really is no other way than adding a state getter to the req object. I don't like this solution, but since the user getter already "pollutes" the req object, also adding adding a state getter is probably not worse. Especially since there is a real use case behind this.

Remaining question would be whether the req.state getter should be added by default or only when a specific option is activated? Opinions are welcome

@rkusa I see no reason not to add ctx to req. With ES6 properties destructuring it you can easily do ({ ctx }, ...) => {}, which gives you full control under your context in strategy. I agree with such a misfortune as lack of passport analogue for koa and thinking about writing koa-based one. For myself, I created temp package, koa-passport-ot.

rkusa commented

Isn't something like

const passport = require('koa-passport')
app.use((ctx, next) => { ctx.req.ctx = ctx; return next() })
app.use(passport.initialize())
app.use(passport.session())

a good enough solution?

If you prefer shorter code, it should also be possible to write something like:

app.use((ctx, next) => (ctx.req.ctx = ctx, next()))

@rkusa first off, thank you for koa-passport it is seriously a life saver!

For what it's worth, I also needed this functionality. I might be worth adding a little disclaimer to the Readme with a link to this issue and the workaround, that way people can find it easily. I do think it feels like something that many apps will need if they're anything more than prototypes, since limiting connections to the database seems like a pretty standard use case.

Another dude here wanting access to the context in a Strategy.

rkusa commented

@ianstormtaylor @basickarl Are you guys interested in the whole context or would the ctx.state be sufficient?

@rkusa The entire ctx in my case. :)

Another vote for ctx. In my case, I need access to headers to get Token Lifetime information.

Vote here for the full ctx. No need for an arbitrary limitation.

rkusa commented

A req.ctx getter is now available in v4.0.0

@rkusa - brilliant, thanks! Do you have an ETA for the 4.x release?

rkusa commented

@leebenson Just published (it is a major release because of the passport update to 0.4.x)