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

403 Forbidden when attempting to fetch user profile #1

Closed
NateBrady23 opened this issue Mar 17, 2022 · 12 comments
Closed

403 Forbidden when attempting to fetch user profile #1

NateBrady23 opened this issue Mar 17, 2022 · 12 comments

Comments

@NateBrady23
Copy link

Thanks for the great work here. I was trying to implement the strategy myself and got a little stuck. This library got me to the point of getting the access token to make requests, but now I can't get past:

 oauthError: {
   statusCode: 403,
     data: '{\n' +
       '  "title": "Forbidden",\n' +
       '  "type": "about:blank",\n' +
       '  "status": 403,\n' +
      '  "detail": "Forbidden"\n' +
   }
 }

I've tried a variety of options for the strategy up to and including the defaults you've provided.

@florianmartens
Copy link
Owner

Hey @nbrady-techempower,

Have you checked your Twitter Developer Portal (the thing you log into and create your Twitter app). Have you checked that you've activated the OAuth 2.0 API and that your app has the required permissions to perform logins via OAuth 2.0?

@NateBrady23
Copy link
Author

Thanks for the quick response @florianmartens.

Oauth 2.0 is active. I'm not sure how I'd check for the latter part of your question. The only other thing I can see that I'm a little iffy on is the Oauth 2.0 settings which I currently have set to Web App.

@florianmartens
Copy link
Owner

florianmartens commented Mar 17, 2022

I'm having some trouble getting into my Twitter Developer Account myself, as it was recently suspended (I went a bit to aggressive with my automations).

I would like to help you debug this. As far as I'm understanding it, you're able to retrieve an access token for a user. The OAuthErroryou're showing above happens when you're trying to make a request e. g. query the /users endpoint. Is that right?

If that is the case, the scope of the error lies somewhat outside of this library as this package should only help you retrieve a valid token. The fact that you're seeing a 403 indicates that you're e. g. missing the correct scope for the request or try to retrieve a resouce that the access token's user does not have permission to view.

@NateBrady23
Copy link
Author

@florianmartens You're absolutely right. It's probably outside the scope of this library, but it is happening during the validation process from within the library when hitting the https://api.twitter.com/2/users/me endpoint, so I just want to make sure it's not a default setting that I'm missing or something the library might be able to catch ahead of time. I can recreate the same error using my IDE's REST client, so it is probable that the access token being sent back doesn't contain the proper scope. I'm using the defaults here: scope: ['tweet.read', 'users.read', 'offline.access']

@florianmartens
Copy link
Owner

Oh, ok - hm. Interesting. If you're able to recreate this error sending the requests via a REST client or in your terminal, it's likely that the cause lies within your app settings. The default scopes should be fine, however.

I'm running this package with NestJS with the following config (not sure if it's helpful since it's close to the defaults in the redme):

    constructor(public readonly configService: ConfigService) {
        super({
            clientID: configService.get<string>('OAUTH_TWITTER_CLIENT_ID'),
            clientSecret: configService.get<string>(
                'OAUTH_TWITTER_CLIENT_SECRET',
            ),
            clientType: 'private',
            callbackURL: configService.get<string>(
                'OAUTH_TWITTER_REDIRECT_URI',
            ),
            passReqToCallback: true,
            pkce: true,
            state: true,
        });
    }

I might be able to be of better help tomrrow if/when I restore access to my own Developer Portal.

@NateBrady23
Copy link
Author

@florianmartens Oh, very cool. I'm also using NestJS.

export class TwitterStrategy extends PassportStrategy(Strategy, 'twitter') {
  constructor(private http: HttpService) {
    super({
      authorizationURL: `https://twitter.com/i/oauth2/authorize`,
      clientType: 'private',
      pkce: true,
      state: true,
      passReqToCallback: true,
      scope: ['tweet.read', 'users.read', 'offline.access'],
      tokenURL: 'https://api.twitter.com/2/oauth2/token',
      customHeaders: {
        Authorization:
          'Basic ' +
          Buffer.from(
            `${configService.getTwitterAuthOptions().clientID}:${
              configService.getTwitterAuthOptions().clientSecret
            }`
          ).toString('base64')
      },
      ...configService.getTwitterAuthOptions()
    });
  }
...

I've actually moved past this to { message: 'Unable to verify authorization request state.' }

Do you mind if I ask what your session middleware settings look like? I have a feeling that's what's going on here.

@florianmartens
Copy link
Owner

florianmartens commented Mar 17, 2022

Ah, this is quite educational for me too. I think, I should probably add some documentation on this although it's more of a Passport feature when using PKCE. PKCE relies on sessions. So make sure to include/accept credentials (both on the client & server):

    import session from 'express-session';

    app.enableCors({
        origin: ['http://localhost:3000', '...'],
        credentials: true,
    });

    app.use(
        session({
            store: new RedisStore({
                client: redisClient,
                host: process.env.REDIS_HOST,
                port: +process.env.REDIS_PORT,
            }),
            secret: process.env.AUTH_SESSION_SECRET,
            resave: false,
            saveUninitialized: false,
        }),
    );

@NateBrady23
Copy link
Author

@florianmartens Thanks so much for your help here. I was actually overwriting some config with the spread operator from my config above as well as some header whitelisting and the incorrect credentials value. This was an existing app and the existing config for session, cors, etc, was a bit complex and I overlooked some things. Thanks again!

@florianmartens
Copy link
Owner

@nbrady-techempower happy to help!

@alphatownsman
Copy link

@nbrady-techempower I encountered similar issue but not using any code in this repo.

It seems to be an issue in Twitter's implementation on API scopes. Basically, in order to access https://api.twitter.com/2/users/me, you have to pass at least users.read tweet.read in scope, users.read alone won't work.

@GorgeousPuree
Copy link

@nbrady-techempower I encountered similar issue but not using any code in this repo.

It seems to be an issue in Twitter's implementation on API scopes. Basically, in order to access https://api.twitter.com/2/users/me, you have to pass at least users.read tweet.read in scope, users.read alone won't work.

omg bruv. I spent 2 days with no idea why it didn't work. I only had users.read in my scopes. May the God stay with you.

@Haisfbmi2019
Copy link

alphatownsman Thank you very much. I spent 2 days for this shit. You are my god

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

5 participants