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

adding state within passport authenticate causes a failure #6

Open
soya-miruku opened this issue Apr 7, 2022 · 9 comments
Open

adding state within passport authenticate causes a failure #6

soya-miruku opened this issue Apr 7, 2022 · 9 comments
Assignees

Comments

@soya-miruku
Copy link

soya-miruku commented Apr 7, 2022

Hey there, I have returned once more,
I am trying to pass additional parameters via my query to the callback function however when I try adding the state
const authenticator = passport.authenticate('twitter', { scope: ['tweet.read', 'users.read', 'follows.read'], state});
authenticator(req, res, next);

the whole auth fails, any idea how I can resolve this?
Note: i know that twitter uses it's own state param, is there way i can add mine on top of it or add a different one

@jnv jnv added the bug Something isn't working label Apr 7, 2022
@jnv jnv self-assigned this Apr 7, 2022
@jnv
Copy link
Collaborator

jnv commented Apr 8, 2022

Hi @VinHylme, I am behind a schedule so I will check this on Monday.

@soya-miruku
Copy link
Author

@jnv no probs, thanks :)

@jnv
Copy link
Collaborator

jnv commented Apr 19, 2022

@VinHylme Thanks for your patience. So passing the state like this should absolutely work, it's actually implemented by the backing passport-oauth2 library and here's a blog post explaining how to use it: https://medium.com/passportjs/application-state-in-oauth-2-0-1d94379164e

The gist is:

  • you need to set store: true in the strategy constructor (ie. new TwitterStrategy)
  • pass the state option into passport.authenticate
  • the state option should be an object

With these options checked, you can then get back your state from req.authInfo.state after you authenticate the callback request, e.g.:

app.get(
  '/auth/twitter/callback',
  passport.authenticate('twitter', {
    failureRedirect: '/error?login'
  }),
  (req, res, next) => {
    console.log('The state is:', req.authInfo.state);
    next();
  }
);

Mind that this isn't a feature of this library, all of this is handled just by the passport-oauth2.

I am removing the bug label but keep this issue open to add this info into our README.

Let me know if it works for you!

@jnv jnv removed the bug Something isn't working label Apr 19, 2022
@MuizNadeem
Copy link

@VinHylme Thanks for your patience. So passing the state like this should absolutely work, it's actually implemented by the backing passport-oauth2 library and here's a blog post explaining how to use it: https://medium.com/passportjs/application-state-in-oauth-2-0-1d94379164e

The gist is:

  • you need to set store: true in the strategy constructor (ie. new TwitterStrategy)
  • pass the state option into passport.authenticate
  • the state option should be an object

With these options checked, you can then get back your state from req.authInfo.state after you authenticate the callback request, e.g.:

app.get(
  '/auth/twitter/callback',
  passport.authenticate('twitter', {
    failureRedirect: '/error?login'
  }),
  (req, res, next) => {
    console.log('The state is:', req.authInfo.state);
    next();
  }
);

Mind that this isn't a feature of this library, all of this is handled just by the passport-oauth2.

I am removing the bug label but keep this issue open to add this info into our README.

Let me know if it works for you!

This was helpful but in my case req.authInfo was undefined always so had to extract it from the session instead.
const state = (req as any)?.session?.['oauth:twitter']?.state?.state;

  '/auth/twitter/callback',
  passport.authenticate('twitter', {
    failureRedirect: '/error?login'
  }),
  (req, res, next) => {
    const state = (req as any)?.session?.['oauth:twitter']?.state?.state;
    console.log('The state is:', state);
    next();
  }
);```

@jatin-threely
Copy link

Hey I am having same issue, it is not working when I am adding custom state like this
passport.authenticate('twitter', { scope: ['tweet.read', 'users.read', 'offline.access'], state: 'twitter' })

I am getting Forbidden error but it is working fine when I am removing state like this
passport.authenticate('twitter', { scope: ['tweet.read', 'users.read', 'offline.access'] })

Twitter OAuth2 strategy within Passport

passport.use(
    new TwitterStrategy(
        {
            clientID: process.env.TWITTER_CLIENT_KEY ?? "",
            clientSecret: process.env.TWITTER_CLIENT_SECRET ?? "",
            clientType: 'confidential',
            callbackURL: 'TWITTER_CALLBACK_URL'
        },
        (accessToken, refreshToken, profile, done) => {
            console.log('Success!', { accessToken, refreshToken, profile });
            const socialMediaPlatform = 'twitter';
            // The user profile obtained from Instagram will be available here
            const user = {
                socialMediaPlatform,
                profile,
            };
            return done(null, user);
        }
    )
);

@janhalama
Copy link
Collaborator

Hi, thanks for your comment. Just a quick guess. Have you tried passing state as an object?

@janhalama
Copy link
Collaborator

You might also find this blog post by Jared helpful.

@jatin-threely
Copy link

Hi, thanks for your comment. Just a quick guess. Have you tried passing state as an object?

Hey, this is working but I can access the state object on my backend when I am making call to the callback URL, then I can send it on client side, but is it possible to access the state object in the call back URL as a params?

@bigint
Copy link

bigint commented Jun 2, 2024

I'm facing this, any fixes?

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

6 participants