Mike Pateras
Mike Pateras

Reputation: 15015

How can I pass a parameter through my passport.js chain?

I'm using passport.js to authenticate users. I would like to be able to pass a username, collected from the user, which will reach the end of the authentication process so that I can store the username when I create the user (if it doesn't yet exist). I've tried this:

app.get("/auth/google", function(request, response)
{
    console.log(request.query.username);

    passport.authenticate("google",
    {
        scope:
        [
            "https://www.googleapis.com/auth/userinfo.profile",
            "https://www.googleapis.com/auth/userinfo.email"
        ]
    })(request, response);
});

app.get("/auth/google/callback", function(request, response)
{
    console.log(request.query.username);

    passport.authenticate("google",
    {
        successRedirect: "/",
        failureRedirect: "htm/error"
    })(request, response);
});

The call to /auth/google prints the username, but the callback prints undefined. Even if I could get the username to the callback, I'm still not sure how I would get it to the google strategy. Would I then have to create my own strategy to get this to work?

Upvotes: 16

Views: 9160

Answers (2)

Kilizo
Kilizo

Reputation: 3382

For anyone using OpenID, req.query seems to be overwritten by the OpenId query params and thus can't be passed through directly. You can attach variables to req.session however.

router.get('/auth/social', (req, res, next) => {
  req.session.foo = req.query.foo;
  next();
}, passport.authenticate('social'));

and don't forget to include the passReqToCallback flag in the strategy options:

{
  passReqToCallback: true,
  returnURL: config.app.returnUrl,
  realm: config.app.realm,
  apiKey: config.app.apiKey
}

Upvotes: 7

Ruben Cordeiro
Ruben Cordeiro

Reputation: 322

You can pass a state object to passport.authenticate, like so:

passport.authenticate("google",
{
    scope:
    [
        "https://www.googleapis.com/auth/userinfo.profile",
        "https://www.googleapis.com/auth/userinfo.email"
    ],
    state: request.query.username
})(request, response);

You can access the state through req.query.state.

The username should be a string, not an object. If you want to store an object in the state, call JSON.stringify before and parse it in the callback.

Upvotes: 13

Related Questions