superfaceai/passport-twitter-oauth2

Twitter displays authorization dialog every time

Opened this issue · 1 comments

Every time I call my passport.authenticate("twitter",...) for the same user, Twitter shows me the standard App wants to access your Twitter account. page. I do see my app in the Connected apps setting with the scopes I requested but still, the authorization page is shown every time.

The authorization page is shown one time only when I use passport-google-oauth20 or passport-facebook. With every subsequent passport.authenticate(...) call it just calls the redirect/callback without showing anything to the user. I would expect the same behaviour for Twitter. Is it possible to achieve this behaviour?

Version: 1.2.2

My configuration:

import { Strategy as TwitterStrategy } from "@superfaceai/passport-twitter-oauth2";
....
  passport.use(new TwitterStrategy({
    clientID: TWITTER_CLIENT_ID,
    clientSecret: TWITTER_CLIENT_SECRET,
    callbackURL: "/auth/twitter/redirect",
    clientType: "confidential"
  }, async (accessToken, refreshToken, profile, done) => {
    console.log("> twitter profile: ", profile);
    ///.....
  }));
router.get("/twitter", passport.authenticate("twitter", { scope: ['tweet.read', 'users.read'] }));

router.get("/twitter/redirect", passport.authenticate("twitter"), (req, res) => {
  res.status(200).json({ success: true });
});

Btw, thanks for the amazing library!

jnv commented

Hi @aderesh! To my knowledge, whether the authorization dialog is shown to the user is completely controlled by the provider. I don't know about any specific parameter or other way to prevent the dialog from showing up (see the docs), but it's possible we're missing something – and then I'd be happy to fix it. If you know about some other Twitter OAuth 2.0 client library where this works as expected, I'll take a look.

If it's feasible for your project, you can prevent user reauthorization by requesting a refresh token and keeping the access token refreshed.

  • Add offline.access scope to your authenticate call
  • In you verify callback, you will receive refreshToken
  • You can use the refresh token to issue a new access token (see docs, you can use e.g. passport-oauth2-refresh or our OneSDK)
    • in my testing the refresh token was valid for a few days (while access token is valid only for ~2 hours)

You could either refresh the access token periodically, or try to refresh it as a last resort before forcing a reauthorization.

Keep in mind that unlike with other providers, refreshing invalidates both the old access token and the old refresh token, you will get both anew.