2025, Nov 17 00:01
Flet 0.21.0 и Discord OAuth: почему не срабатывает on_login и что делать
Проблема Discord OAuth в Flet 0.21.0: on_login не вызывается из‑за нового эндпоинта /oauth_callback. Как настроить redirect_url, чтобы авторизация заработала.
При интеграции Discord OAuth в приложение на Flet всё может выглядеть корректно: появляется кнопка входа, браузер запрашивает авторизацию, а URL перенаправления возвращает на ваш localhost. Однако обработчик on_login так и не срабатывает. Причина неброская, но простая: в Flet 0.21.0 изменился эндпоинт обратного вызова OAuth.
Демонстрация проблемы
Следующий фрагмент показывает типичную настройку, при которой в браузере аутентификация проходит успешно, но обработчик on_login в приложении ни разу не вызывается.
import os
import flet
from flet import ElevatedButton, Page
from flet.auth import OAuthProvider
def app_entry(screen: Page):
discord_auth = OAuthProvider(
client_id=os.getenv("DISCORD_CLIENT_ID"),
client_secret=os.getenv("DISCORD_CLIENT_SECRET"),
authorization_endpoint="https://discord.com/oauth2/authorize",
token_endpoint="https://discord.com/api/oauth2/token",
scopes=["identify","guilds","email","guilds.join","guilds.members.read"],
redirect_url="http://localhost:2000/api/auth/discord/redirect",
)
def handle_signin(evt):
screen.login(discord_auth)
print("hello")
def after_login(evt):
screen.add(flet.Text("on_logi called"))
print("on_logi called", flush=True)
if evt.error:
screen.add(ElevatedButton(f"Login error: {evt.error}"))
return
screen.add(ElevatedButton(f"User ID: {screen.auth.user.id}"))
screen.add(ElevatedButton(f"Access token: {screen.auth.token.access_token}"))
screen.add(flet.Text("HELLOO DID IT WORK?"))
screen.on_login = after_login
screen.add(ElevatedButton("Login with Discord", on_click=handle_signin))
flet.app(app_entry, port=2000, view=flet.WEB_BROWSER)Что происходит на самом деле и почему
Начиная с Flet 0.21.0, из‑за перехода веб‑сервера на FastAPI URL‑эндпоинт обработчика OAuth изменился с /api/oauth/redirect на /oauth_callback. Если ваш redirect_url (и Redirect URI в настройках приложения Discord) указывает на другой путь, фреймворк не попадёт во внутренний обработчик, который триггерит page.on_login, поэтому ваш колбэк не запустится.
Решение
Направьте перенаправление на новый эндпоинт. Используйте /oauth_callback в качестве адреса возврата OAuth. Если нужен другой путь, его можно переопределить переменной окружения FLET_OAUTH_CALLBACK_HANDLER_ENDPOINT.
import os
import flet
from flet import ElevatedButton, Page
from flet.auth import OAuthProvider
def app_entry(screen: Page):
discord_auth = OAuthProvider(
client_id=os.getenv("DISCORD_CLIENT_ID"),
client_secret=os.getenv("DISCORD_CLIENT_SECRET"),
authorization_endpoint="https://discord.com/oauth2/authorize",
token_endpoint="https://discord.com/api/oauth2/token",
scopes=["identify","guilds","email","guilds.join","guilds.members.read"],
redirect_url="http://localhost:2000/oauth_callback",
)
def handle_signin(evt):
screen.login(discord_auth)
print("hello")
def after_login(evt):
screen.add(flet.Text("on_logi called"))
print("on_logi called", flush=True)
if evt.error:
screen.add(ElevatedButton(f"Login error: {evt.error}"))
return
screen.add(ElevatedButton(f"User ID: {screen.auth.user.id}"))
screen.add(ElevatedButton(f"Access token: {screen.auth.token.access_token}"))
screen.add(flet.Text("HELLOO DID IT WORK?"))
screen.on_login = after_login
screen.add(ElevatedButton("Login with Discord", on_click=handle_signin))
flet.app(app_entry, port=2000, view=flet.WEB_BROWSER)Ссылка: из обсуждений на GitHub — Flet Authentication providers problem · flet-dev/flet · Discussion #2950.
Почему это важно
Потоки OAuth крайне чувствительны к URI перенаправления. Несоответствие между тем, что использует провайдер идентификации, и тем, чего ждёт ваше приложение, обычно приводит к «тихим» сбоям: в браузере всё завершается, но приложение не получает токен и не вызывает хук входа. Зная точный эндпоинт, который использует фреймворк, вы избегаете часов отладки вкладок и серверных логов.
Что важно запомнить
Для Flet 0.21.0 и новее убедитесь, что и в настройках приложения Discord, и в вашем коде для перенаправления используется /oauth_callback. Если развёртыванию нужен свой путь, задайте его через переменную окружения FLET_OAUTH_CALLBACK_HANDLER_ENDPOINT. Достаточно согласовать эти значения — и on_login снова начнёт выполняться, а в приложении появится доступ к аутентифицированному пользователю и токену.