Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a way to maintain query params from the initial request? #96

Open
christopher-francisco opened this issue Feb 8, 2018 · 9 comments

Comments

@christopher-francisco
Copy link

I have this route:

router.get('/auth', passport.authenticate('oauth2'));

When I visit /auth?redirect_to=myInitialEncodedURL, I get redirected to the oauth endpoint, without the redirect_to parameter:

/oauth/auth?response_type=code&redirect_uri=encodedURLFor`auth/callback`&client_id=my-clientId

But there's no redirect_to parameter. Is there any way this can be done?

@itajaja
Copy link

itajaja commented Mar 28, 2018

Here is my solution, achieved with subclassing

class MyStrategy extends OauthStrategy {
  authenticate(req: Request, options) {
    // tslint:disable-next-line:no-string-literal
    const callbackURL = options.callbackURL || this['_callbackURL']
    options.callbackURL = addReturnTo(req, callbackURL)
    return super.authenticate(req, options)
  }
}

@alkerway
Copy link

To have a dynamic redirectUri via the options I had to change the following in strategy.js

if (callbackURL) { params.redirect_uri = callbackURL; }

to

if (options.redirectUri) {
  params.redirect_uri = options.redirectUri;
} else if (callbackURL) {
  params.redirect_uri = callbackURL;
}

and pass in the redirectUri with query parameters in the passport.authenticate() call, which I was doing anyways.

If it's worth making a pr I'd be happy to

@dgolant
Copy link

dgolant commented Jul 8, 2018

I've been looking for a solution for this for a month. I was trying to use the passReqToCallback option but it wasn't working.

@itajaja
Copy link

itajaja commented Jul 9, 2018

@dgolant you can use state. here is how I do:

app.get(`/auth`, (req, res, next) => {
      const { returnTo } = req.query
      const state = returnTo
        ? new Buffer(JSON.stringify({ returnTo })).toString('base64')
        : undefined

      const authenticator = passport.authenticate('google', { scope: [], state })

      authenticator(req, res, next)
    })
    app.get(
      `/auth/callback`,
      passport.authenticate('google', { failureRedirect: '/-/login' }),
      (req, res) => {
        try {
          const { state } = req.query
          const { returnTo } = JSON.parse(new Buffer(state, 'base64').toString())
          if (typeof returnTo === 'string' && returnTo.startsWith('/')) {
            return res.redirect(returnTo)
          }
        } catch {
          // just redirect normally below
        }
        res.redirect('/')
      },
    )

@aoberoi
Copy link

aoberoi commented Sep 18, 2018

@itajaja provided an awesome solution. i just wanted to mention that the new Buffer() constructor is deprecated, so instead you should use Buffer.from().

@albertonzn
Copy link

@itajaja , Do I need to enable sessions (express-session) in your solution? Because every time i try to access state in the callback i get undefined.

@itajaja
Copy link

itajaja commented Oct 26, 2020

@albertonzn as far as I recall, you don't. there must be some other minor issue going on on your side

@albertonzn
Copy link

@itajaja , thanks for you reply. It was a minor bug on my side. Everything is working now.

@apiel
Copy link

apiel commented Nov 16, 2021

Is there any update on this issue to keep query params from initial request? Cause so far all proposed solutions are work around. What is the reason to remove the query params from the request?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants