When doing a "local" verify call I need more information than just the username and password. By default I don't see a way to pass extra data to the verify function. Would you take patches? What would be the "passportjs-style" of doing it?
What information are you needing? I'd prefer to keep only authentication related parameters going to the verify call, but I'm open to adding more if there is a compelling reason.
If you have application-specific parameters you need to handle, my recommendation is to do that work in a custom callback, such as:
app.post('/login', function(req, res, next) {
passport.authenticate('local', function(err, user) {
if (err) { return next(err) }
if (!user) { return res.redirect('/unauthorized') }
// do app-specific stuff here
req.logIn(user, ...);
})(req, res, next);
});
Let me know the details. I'll gladly take patches, or offer up alternative suggestions. It's early days, so even I'm still figuring out "passportjs-style"!
To know where/how to lookup a user we need a "brand" derived from incoming host header, cookies, ssl cert or something else in req.
I agree that the verify function shouldn't have or need access to the full req/res objects, but I think a way to parse "here's something else you should know" would be a generally useful addition. (even if it could be abused to pass req/res/.. ;-) )
Ask
Ask -
Picking up the thread on this issue, now that I've got all the higher priority features in place. I'm warming up to the idea of making it an _option_ to pass req
to the verify callback. If I implement this, it'd look something like this:
passport.use(new LocalStrategy({ passReqToCallback: true }
function(req, username, password, done) {
// ...
}
));
If you set passReqToCallback
to true
, then req
becomes the first argument to the verify callback. You could use that to inspect sessions, hosts, certs, etc. The default for this option would be false
(ie, things work exactly the same as before), and verify callbacks would still be the recommended way to tie together the request with the auth result.
Any thoughts? Also, I'm curious what solution you've arrived at in the meantime, if any. Thanks!
Right now I am just stashing the data I need into app (so a global basically) and hoping or the best. Not ideal, to put it mildly!
I am on my phone right now, either tonight or in a few days I will reply again and see if I can come up with some alternatives that are more flexible.
Alright, to re-state my use case in great detail:
Our application is configured with a "master" API key and hostname to access a backend API. On startup it'll use this key to fetch a bunch of other configuration, hostnames to respond to and corresponding API keys for the backend API for each "site". The application can also get reconfigured in real-time via redis publish/subscribe messages.
Then on each user request, we setup what is basically a data model of sorts to access the backend data API with the appropriate API key for the current hostname. I think another similar use-case would be that you have different database connections for different sites.
To authenticate a user we need the particular "per request" data model. Right now I store it in app.set(), but that'll break if we get two requests to authenticate too close to each other. Oops!
The passReqToCallback
option is now implemented for the local strategy. Works as described here.
I think this should be sufficient for your scenario. Thanks for pushing Passport to its limits, and let me know if any other requirements come up!
Thank you @jaredhanson, and abh for pushing for this! Critical to my use case.
Most helpful comment
The
passReqToCallback
option is now implemented for the local strategy. Works as described here.I think this should be sufficient for your scenario. Thanks for pushing Passport to its limits, and let me know if any other requirements come up!