To implement OAuth authentication in a headless environment (where you don't have a direct browser interface, such as a web server), use the UserAuthenticator class. This involves setting up a web server (like Flask) to handle the redirect from Twitch.
Workflow
- Configure Twitch Dashboard: Add your redirect URL (e.g.,
http://localhost:5000/login/confirm) as an "OAuth Redirect URL" in the Twitch Developer Console. - Initialize Twitch and Authenticator: Create a
Twitch instance and pass it to UserAuthenticator along with your desired AuthScope and your redirect url. - Redirect to Twitch: Create a route (e.g.,
/login) that redirects the user to the URL generated by auth.return_auth_url(). - Handle Callback: Create a callback route (e.g.,
/login/confirm) to receive the state and code parameters from Twitch.- Verify that the
state from the request matches auth.state to prevent CSRF. - Use
await auth.authenticate(user_token=code) to exchange the code for tokens. - Use
await twitch.set_user_authentication(token, TARGET_SCOPE, refresh) to apply the new authentication to your Twitch instance.
Implementation Example
import asyncio
from twitchAPI.twitch import Twitch
from twitchAPI.oauth import UserAuthenticator
from twitchAPI.type import AuthScope, TwitchAPIException
from flask import Flask, redirect, request
APP_ID = 'my_app_id'
APP_SECRET = 'my_app_secret'
TARGET_SCOPE = [AuthScope.CHAT_EDIT, AuthScope.CHAT_READ]
MY_URL = 'http://localhost:5000/login/confirm'
app = Flask(__name__)
twitch: Twitch
auth: UserAuthenticator
@app.route('/login')
def login():
return redirect(auth.return_auth_url())
@app.route('/login/confirm')
async def login_confirm():
state = request.args.get('state')
if state != auth.state:
return 'Bad state', 401
code = request.args.get('code')
if code is None:
return 'Missing code', 400
try:
token, refresh = await auth.authenticate(user_token=code)
await twitch.set_user_authentication(token, TARGET_SCOPE, refresh)
except TwitchAPIException as e:
return 'Failed to generate auth token', 400
return 'Sucessfully authenticated!'
async def twitch_setup():
global twitch, auth
twitch = await Twitch(APP_ID, APP_SECRET)
auth = UserAuthenticator(twitch, TARGET_SCOPE, url=MY_URL)
asyncio.run(twitch_setup())
import asyncio
from twitchAPI.twitch import Twitch
from twitchAPI.oauth import UserAuthenticator
from twitchAPI.type import AuthScope, TwitchAPIException
from flask import Flask, redirect, request
APP_ID = 'my_app_id'
APP_SECRET = 'my_app_secret'
TARGET_SCOPE = [AuthScope.CHAT_EDIT, AuthScope.CHAT_READ]
MY_URL = 'http://localhost:5000/login/confirm'
app = Flask(__name__)
twitch: Twitch
auth: UserAuthenticator
@app.route('/login')
def login():
return redirect(auth.return_auth_url())
@app.route('/login/confirm')
async def login_confirm():
state = request.args.get('state')
if state != auth.state:
return 'Bad state', 401
code = request.args.get('code')
if code is None:
return 'Missing code', 400
try:
token, refresh = await auth.authenticate(user_token=code)
await twitch.set_user_authentication(token, TARGET_SCOPE, refresh)
except TwitchAPIException as e:
return 'Failed to generate auth token', 400
return 'Sucessfully authenticated!'
async def twitch_setup():
global twitch, auth
twitch = await Twitch(APP_ID, APP_SECRET)
auth = UserAuthenticator(twitch, TARGET_SCOPE, url=MY_URL)
asyncio.run(twitch_setup())