PLhery / node-twitter-api-v2

Strongly typed, full-featured, light, versatile yet powerful Twitter API v1.1 and v2 client for Node.js.
https://www.npmjs.com/package/twitter-api-v2
Apache License 2.0
1.31k stars 181 forks source link

[bug] Authenticating with OAuth 2.0 Application-Only is forbidden for this endpoint. Supported authentication types are [OAuth 1.0a User Context, OAuth 2.0 User Context] #475

Open sarathkmrdev opened 1 year ago

sarathkmrdev commented 1 year ago

Describe the bug i am getting below error when creating tweet using v2 api . data: { title: 'Unsupported Authentication', detail: 'Authenticating with OAuth 2.0 Application-Only is forbidden for this endpoint. Supported authentication types are [OAuth 1.0a User Context, OAuth 2.0 User Context].', type: 'https://api.twitter.com/2/problems/unsupported-authentication', status: 403 }

To Reproduce I have attached code below

const { TwitterApi } = require('twitter-api-v2'); const client = new TwitterApi(''); let createdTweet = await client.v2.tweet('twitter-api-v2 is awesome!'); console.log('Tweet', createdTweet);

Version

Additional context I have registered for developer account with Basic plan.

locnt19 commented 1 year ago

Hi @sarathkmrdev, I think you should authenticate yourself before calling the API. I recommend using the OAuth2 method and storing the accessToken and refreshToken. You can then use them to call the API on behalf of this user with simple code below

const API = new TwitterApi({ clientId: 'CLIENT_ID', clientSecret: 'CLIENT_SECRET' });
const { accessToken } = await API.refreshOAuth2Token('YOUR_REFESHTOKEN');
const client = new TwitterApi(accessToken);
const tweet = await client.v2.tweet('It works!');
console.log('Tweet Result', tweet);
comapedrosa commented 1 year ago

Hello @locnt19 I tried your approach but since I want to tweet from my own developer account I changed it to:

const client = new TwitterApi(MY_BEARER_TOKEN);
const tweet = await client.v2.tweet('It works!');

but the response I get is:

  data: {
    title: 'Unsupported Authentication',
    detail: 'Authenticating with OAuth 2.0 Application-Only is forbidden for this endpoint.  Supported authentication types are [OAuth 1.0a User Context, OAuth 2.0 User Context].',
    type: 'https://api.twitter.com/2/problems/unsupported-authentication',
    status: 403
  }

Any idea why this happens? Have I done something wrong?

nightspite commented 1 year ago

Twitter has basically 3 OAuth methods:

By passing the Bearer token from Twitter's Developer Dashboard you opt-in for the last option. With Application Only flow you basically have access to only public information, if you want to use for example POST endpoints, like the one for creating a tweet, you need to use User Context OAuth.

That might be helpful https://github.com/PLhery/node-twitter-api-v2/blob/master/doc/auth.md#user-wide-authentication-flow

So in summary: You have to somehow obtain an access token.

  1. Use generateOAuth2AuthLink fn to generate an auth url
    
    const callbackUrl = 'http://127.0.0.1:3001/callback';
    const twitterClient = new TwitterApi({
    clientId: TWITTER_CREDENTIALS.CLIENT_ID,
    clientSecret: TWITTER_CREDENTIALS.CLIENT_SECRET,
    });

const state = randomUUID();

const authUrl = this.twitterClient.generateOAuth2AuthLink( callbackUrl, { state, scope: ['tweet.read', 'tweet.write', 'users.read', 'offline.access'], }, ); const codeVerifier = authUrl.codeVerified;

2. Open the generated URL and sign in with twitter.
3. Create a callback endpoint, where you can be redirected after a successful auth on Twitter page.
    You should get code & state in query params
```ts
const tokenResult = await this.twitterClient.loginWithOAuth2({
    code,
    codeVerifier,
    redirectUri: callbackUrl,
});
  1. Token result will consist of accessToken, refreshToken, expiresIn & scope. Save them somewhere and use the accessToken to create a different twitter client.
    
    const twitterClient = new TwitterApi(accessToken);

const response = await twitterClient.v2.tweet(data.text);


5. Create an interceptor that would handle the case when Twitter API throws 401 error and refresh the token using the refreshToken and `refreshOAuth2Token` method.
izdrail commented 1 year ago

I'm using php and using the access token that I've got from using the same principle , I'm getting the same error .

asafd1 commented 11 months ago

Same. getting this error with this python code:


oauth2_user_handler = tweepy.OAuth2UserHandler(
    client_id=client_id,
    redirect_uri=redirect_uri,
    scope=scopes,
    client_secret=client_secret,
)

auth_url = oauth2_user_handler.get_authorization_url()

print('Please authorize this application: {}'.format(auth_url))

verifier = input('Enter the authorization response URL:')
token = oauth2_user_handler.fetch_token(verifier)
client = tweepy.Client(access_token=token['access_token'])
user = client.get_me(user_auth=False)