0

I've seen lots of related questions to this one, but none of the answers have helped me.

First, I went to the Twitter Developer Portal and set up my OAuth2.0 Client ID and Secret:

enter image description here

Then, I used Authlib to set up a OAuth2Session with an Authorization Code flow, documented here:

authorization_url = 'https://api.twitter.com/2/oauth2/authorize'
scopes = ['tweet.read', 'tweet.write', 'users.read']
scope = ' '.join(scopes)

Then I set up an OAuth2 client using the ID and secret, create the authorization URL, and print the URI for use:

client = OAuth2Session(client_id, client_secret, scope=scope)
uri, state = client.create_authorization_url(authorization_url)
print("> Open this in your browser: " + uri)

In the terminal, it prints

> Open this in your browser: https://api.twitter.com/2/oauth2/authorize?response_type=code&client_id=[redacted]&scope=tweet.read+tweet.write+users.read&state=L21JiPkirR8awYs7kcDjFC4jrPj68x

But opening the link in a browser displays the Twitter-produced error

{"errors":[{"message":"Bad Authentication data","code":215}]}

which is all over Stack Overflow. So I tried

  • logging out of Twitter again,
  • opening the link on various browsers,
  • removing the scope parameter from the OAuth2Session object,
  • changing the scope join character from ' ' to '%20' and '+',
  • double-checking and regenerating Client ID + Secret,
  • removing Authlib and implementing the same code using just Python requests

I believe another answer (and others like these) fail to help in my situation because Authlib's OAuth2Session should be correctly set up and authenticating via OAuth2 (unless there's a problem with the library).

So, after that, I tried adding the callback URI through the client. I used a local callback URI with a Flask app. This is the same Callback URI I set up in the Twitter developer portal. Although this probably isn't done correctly, I don't believe it's causing Error 215. I thought I'd include this just in case:

callback_uri = 'http://127.0.0.1:5000/oauth/callback'

client = OAuth2Session(client_id, client_secret, scope=scope, redirect_uri=callback_uri)
from flask import Flask
app = Flask(__name__)

@app.route("/oauth/callback", methods=["GET"])
def callback():
    print('Callback')

I could be missing something, or perhaps my data is improperly formatted in some way. This has proven to be a frustrating issue.

Ben Myers
  • 1,173
  • 1
  • 8
  • 25

1 Answers1

0

If the type of library is not important to you and you only want the output, I recommend you to use the Tweepy library, because it has a mode that does not require a callback and only works with pin. Pay attention to the following example:

import tweepy
auth = tweepy.OAuthHandler(
    "CONSUMER_KEY",
    "CONSUMER_SECRET",
    callback='oob'
)
auth_url = auth.get_authorization_url()
print("\n", auth_url, "\n")
verifier_value = input("Enter Authorization Pin: ")
auth.get_access_token(verifier_value)
text = f"Consumer key: {CONSUMER_KEY}\n"
text += f"Consumer secret: {CONSUMER_SECRET}\n"
text += f"Access token: {auth.access_token}\n"
text += f"Access token secret: {auth.access_token_secret}\n"
print(text)

Whenever you set the value of the callback parameter to oob, Twitter authenticates will be changed

Mohammad Zarchi
  • 111
  • 1
  • 8
  • Hi Mohammad, thanks for the answer. Sadly I cannot use any Twitter-based libraries, as the code I’m writing is going to be extended to other API’s in the future. I have to take the OAuth2 session approach, and in this case, I’m starting with authorization code flow. – Ben Myers Dec 26 '22 at 16:46