passportjs facebook pass request to callback

I must be overlooking something here. I'm using the Facebook strategy of passportjs to authenticate users. This is done with 2 requests/[route handlers]:

//one to initiate the the auth:
init: function (req, res, next) {
    passport.authenticate('facebook', {
        callbackURL: URL + '/facebook/callback',
        state: req.body //attempting to put some state
    })(req, res, next)
}

//one callback
callback: function (req, res, next) {
    passport.authenticate('facebook', {
        callbackURL: URL + '/facebook/callback'
    },
    function (err, profile, accessToken, refreshToken) {
        if (err) return next(err)
        res.send(passedReqBody)
    })(req, res, next)
}

//the verify callback doesn't do much.
//Application logic is done in route callback handlers
passport.use(new FacebookStrategy({
    clientID: config.facebook.id,
    clientSecret: config.facebook.secret
},
//When setting passReqToCallback to true, it is set as the first argument
//to the verify callback. As in:
//function (req, accessToken, refreshToken, params, profile, done) {
//But this is the 'callback' request object. I want the 'init' request object.
function (accessToken, refreshToken, params, profile, done) {
    //params.state is undefined
    return done(null, profile, accessToken, refreshToken);
}));

My problem is that I want the POST request body of the first function to be exposed in the callback route handler.

There is an option available to the OAuth2Strategy constructor 'passReqToCallback' which sends the latest request back to the verify callback, which is not useful to me (I want the first request.body)

The next thing that looked a plausible path, was the use of the 'state' option, as in https://github.com/jaredhanson/passport-oauth/blob/master/lib/passport-oauth/strategies/oauth2.js#L169

But these values aren't available on the getOAuthAccessToken callback https://github.com/jaredhanson/passport-oauth/blob/master/lib/passport-oauth/strategies/oauth2.js#L124

My current option is to add an extra variable inside the OAuth2Strategy.prototype.authenticate() function, which gets set on the 1st function, and passed back, unchanged, to the callback function, but I can't imagine this is the way to go.

From what you describe, the best approach may be dependent on your application, but here's a quick modification of your init and callback middleware:

init: function (req, res, next) {
    // SAVE BODY IN SESSION
    req.session.initBody = req.body;

    passport.authenticate('facebook', {
        callbackURL: URL + '/facebook/callback',
        state: req.body //attempting to put some state
    })(req, res, next)
}

//one callback
callback: function (req, res, next) {
    passport.authenticate('facebook', {
        callbackURL: URL + '/facebook/callback'
    },
    function (err, profile, accessToken, refreshToken) {
        if (err) return next(err)
        // RESTORE BODY FROM SESSION
        res.send(req.session.initBody);
        delete req.session.initBody;
    })(req, res, next)
}

Note that the original request body is being persisted to the session and then restored upon callback. If you want data to survive a request/response cycle, this is one technique to do it. I'd caution, however, that mutating state in the GET callback may not be advisable, so be careful if you modify anything based on the original body.