2025, Nov 12 01:00

Discord OAuth not triggering on_login in Flet 0.21.0: use /oauth_callback or set FLET_OAUTH_CALLBACK_HANDLER_ENDPOINT

Discord OAuth works in the browser but on_login never fires in Flet 0.21.0. Set the redirect to /oauth_callback or customize the callback endpoint to fix login.

When integrating Discord OAuth in a Flet app, everything may look correct: the login button appears, the browser prompts for authorization, and the redirect URL lands back on your localhost. Yet the on_login handler never fires. The root cause is subtle but straightforward: the OAuth callback endpoint changed in Flet 0.21.0.

Problem demonstration

The following snippet shows a typical setup where authentication succeeds in the browser but the application-side on_login handler is never called.

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)

What actually happens and why

Starting with Flet 0.21.0, due to migration to fast Api on web server, the OAuth handler URL Endpoint changed from /api/oauth/redirect to /oauth_callback. If your redirect_url (and the Discord application’s redirect URI) points to another path, the framework won’t hit the internal handler that triggers page.on_login, so your callback never runs.

Fix

Point the redirect to the new endpoint. Use /oauth_callback as the OAuth redirect target. If you need a different path, you can customize it with the FLET_OAUTH_CALLBACK_HANDLER_ENDPOINT environment variable.

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)

Reference: From discussions in GitHub — Flet Authentication providers problem · flet-dev/flet · Discussion #2950.

Why this matters

OAuth flows are extremely sensitive to redirect URIs. A mismatch between what your identity provider uses and what your application expects typically results in silent failures: the browser completes, but the app doesn’t get a token or fire the login hook. Knowing the exact endpoint used by the framework avoids hours of debugging browser tabs and server logs.

Takeaways

For Flet 0.21.0 and later, ensure your Discord application and your code use /oauth_callback for the redirect. If your deployment needs a custom path, set it via the FLET_OAUTH_CALLBACK_HANDLER_ENDPOINT environment variable. Aligning these values is enough to restore the on_login execution and access the authenticated user and token in your app.

The article is based on a question from StackOverflow by AKSG and an answer by AKSG.