New in reflex-enterprise v0.9.1.
Authentication Overview
rxe.AuthPlugin adds OIDC
(OpenID Connect) authentication to Reflex apps. Add the plugin to
rxe.Config(plugins=[...]), set the provider environment variables, and use
rxe.App().
By default, every page, event handler, base field, and computed var requires an
authenticated user. Use auth=False for surfaces that should be public.
The plugin runs the OIDC Authorization Code + PKCE flow against your identity
provider (IdP) and registers /login, /logout, /callback, and /forbidden
routes.
Quickstart
1. Add rxe.AuthPlugin() to rxconfig.py and configure your OIDC provider
through the OIDC_* environment variables:
With the OIDC_* variables set, the app imports and compiles before the IdP is
reachable. OIDC discovery runs only when a user logs in. Placeholder values are
enough for local builds and CI.
2. Use rxe.App() (not rx.App()) in your app module:
3. Register the redirect URI with your IdP. Add the plugin's
auth_callback_endpoint (/callback by default) as an allowed redirect URI in
your identity provider's client settings. Register the full URL (scheme,
host, and path) for each environment. A mismatched value produces
redirect_uri_mismatch; see
deploying to production for the exact
callback URL.
You don't need to write a provider class. The plugin uses the built-in
GenericOIDCAuthState, which reads those variables. See
providers for named and multi-provider
setups.
The four protected surfaces
Once active, the plugin protects four kinds of surface by default:
auth=True is the default everywhere, so a plain rx.field(...) or bare
@rxe.var is already protected. Set auth=False to make a surface public.
See secure by default for the full
enforcement model, the four auth= wrappers, and authorization check functions.
Reading the current user
reflex_enterprise.auth.User is an alias of
reflex_enterprise.auth.AuthUserState. Use its class-level Vars directly in
components. They are populated by the provider that authenticated the user:
Inside an event handler, await User.current() returns the user's
OIDCUserInfo claims dict (or None when anonymous):
See reading the current user
for the full User API, including frontend Vars, current(), and
current_provider().
Signing out
Sign the user out by linking to /logout or by binding the User.logout event:
User.logout signs out whichever provider the user logged in with, so it works
with multiple providers. If no one is signed in there's nothing to sign out, so
it just sends them back to the home page (/).
Example header:
How a login flows end to end
- An anonymous visitor hits a protected page (or calls a protected handler) and
is redirected to
/login, with the requested page preserved as aredirect_toquery parameter. /loginrenders a button per configured provider. The visitor clicks one and is sent to the IdP's authorization endpoint (Authorization Code + PKCE).- The IdP authenticates the user and redirects back to
/callback, which validates the OAuthstate(CSRF), exchanges the code for tokens, and stores them in secure cookies. - The user is redirected back to
redirect_to. Protected fields, vars, pages, and handlers now resolve against the authenticated user. /logoutclears tokens, resets the protected surface of every state, and chains the provider's logout. A CSRF guard blocks cross-site logout requests (see secure by default).
Related
- Secure by default: enforcement,
auth=, authorization checks, and theUserfacade. - Providers: provider classes, environment variables, scopes, and multi-provider setups.
- Custom pages: custom
/login,/callback,/logout, and/forbiddencomponents. - Testing: authorization checks and mock-IdP integration tests.
- Deploying to production: HTTPS, callback URLs, reverse proxies, and troubleshooting.
- Enterprise overview: other Enterprise features.