Implement OAuth 2.0 with PKCE for secure user authentication
OAuth 2.0 with PKCE (Proof Key for Code Exchange) is the recommended authentication method for XDK Python. It provides enhanced security and supports automatic token refresh.
Create a Client instance with OAuth 2.0 credentials:
from xdk import Clientclient = Client( client_id="your_client_id", client_secret="your_client_secret", # Optional for public clients redirect_uri="https://yourapp.com/callback", scope="tweet.read tweet.write users.read")
The Client automatically creates an OAuth2PKCEAuth instance when you provide client_id.
2
Get Authorization URL
Generate the authorization URL and redirect the user:
# Get authorization URL (PKCE parameters generated automatically)auth_url = client.get_authorization_url(state="random_state_string")print(f"Visit this URL to authorize: {auth_url}")# Redirect user to auth_url in your web app
The code verifier and challenge are automatically generated and stored at oauth2_auth.py:78.
3
Handle Callback
After the user authorizes, X redirects to your redirect_uri with a code parameter:
Extract the authorization code from the callback URL.
4
Exchange Code for Token
Exchange the authorization code for access and refresh tokens:
# Using the code from callbacktoken = client.exchange_code(code="AUTH_CODE")print(f"Access Token: {token['access_token']}")print(f"Refresh Token: {token['refresh_token']}")print(f"Expires In: {token['expires_in']} seconds")
Store the refresh token securely. It’s used to obtain new access tokens without user interaction.
5
Make Authenticated Requests
The client is now authenticated and ready to use:
# Access token is automatically used for requestsuser = client.users.get_me()print(f"Authenticated as: @{user.data.username}")# Create a tweettweet = client.posts.create_tweet(text="Hello from XDK Python!")print(f"Tweet ID: {tweet.data.id}")
# As a space-separated stringclient = Client( client_id="...", scope="tweet.read tweet.write users.read follows.read follows.write")# Or as a listclient = Client( client_id="...", scope=["tweet.read", "tweet.write", "users.read", "follows.read", "follows.write"])
For advanced use cases, you can manually set PKCE parameters:
from xdk.oauth2_auth import OAuth2PKCEAuthauth = OAuth2PKCEAuth( client_id="your_client_id", redirect_uri="https://yourapp.com/callback", scope="tweet.read users.read")# Set custom code verifierauth.set_pkce_parameters( code_verifier="your_code_verifier", code_challenge="your_code_challenge" # Optional, will be generated if not provided)# Get the parametersverifier = auth.get_code_verifier()challenge = auth.get_code_challenge()
The code challenge is generated at oauth2_auth.py:89 using SHA-256 hashing.
try: token = client.exchange_code(code="invalid_code")except ValueError as e: print(f"Code exchange failed: {e}") # Show error to user and restart OAuth flowtry: token = client.refresh_token()except ValueError as e: if "client_secret is required" in str(e): print("Cannot refresh - public client") # Re-authenticate user elif "No token to refresh" in str(e): print("No existing token") # Start new OAuth flow else: print(f"Refresh failed: {e}")
# Using the complete callback URLcallback_url = "https://yourapp.com/callback?code=AUTH_CODE&state=random_state"token = client.fetch_token(authorization_response=callback_url)
The fetch_token() method at oauth2_auth.py:202 internally uses exchange_code() for compatibility.