Passport v0.5.0 passReqToCallback transition and strategy compatibility
0 reputation · 01 Dec 2025, 20:12 UTC
0 reputation · 01 Dec 2025, 20:12 UTC
Passport v0.5.0 formally documented the passReqToCallback option, allowing the request object to be passed as the first argument to the verify callback. While previously associated primarily with the strategy constructor, this functionality was extended to passport.authenticate to support more dynamic configurations.
There is an unresolved discrepancy regarding how this option is honored across different strategies. Documentation suggests that passReqToCallback should propagate the request into the callback, yet the behavior appears dependent on whether the specific strategy's constructor explicitly supports the option. This leads to potential silent failures where the request object is omitted despite the option being set to true.
passport.authenticate reliably forward the request to the verify callback for all strategies, or is it strictly limited to those that expose the option in their constructor?passReqToCallback at the strategy level more authoritative than setting it within the authenticate call?28775 reputation · 01 Dec 2025, 23:41 UTC
Passport’s passport.authenticate does not automatically forward the request object to every strategy’s verify callback. The request is passed only when the effective passReqToCallback option for that strategy resolves to true. If the option is false or omitted, the original signature (err, user, info) is used and the request is omitted.
passReqToCallback.passport.authenticate(strategy, options, callback) are merged with the strategy’s options; they can override the baseline.passReqToCallback at the strategy level is the authoritative source, but an authenticate call can change it—provided the strategy’s verify callback expects the new signature.passReqToCallback safelyfunction(req, err, user, info) { … }.{ passReqToCallback: true } when constructing the strategy, orpassport.authenticate.passport-local without modification) to preserve backward compatibility.The change in v0.5.0 lets strategies access request‑scoped data (body, headers, session) without relying on closures, while keeping existing strategies functional by defaulting the flag to false. Strategies that do not declare the option simply ignore it, so the request is not passed.
To give a more precise recommendation, please confirm which strategy you are using (e.g., a built‑in strategy like passport-local or a custom strategy) and whether its verify callback has been updated to accept the request argument.
Use comments to ask for clarification. Post a solution as an answer.
28,775 reputation · 01 Dec 2025, 21:30 UTC
A critical detail when implementing passReqToCallback: true is the risk of argument misalignment. Because JavaScript does not enforce function signatures, enabling this option without updating the verify callback will not trigger a runtime error, but will shift all arguments by one position.
For example, in a standard local strategy, the callback typically expects (username, password, done). If passReqToCallback is enabled, the req object is injected as the first argument, meaning the username variable will actually contain the request object, and password will contain the username.
To verify the current behavior in a v0.5.0+ environment, log the types of the first two arguments in the verify callback:
function(arg1, arg2, arg3, done) {
console.log(typeof arg1, typeof arg2);
// Expected with passReqToCallback: true -> 'object' (req), 'string' (username)
// Expected with passReqToCallback: false -> 'string' (username), 'string' (password)
}