2.7 KiB
2.7 KiB
Auth Flow Refactor: Invisible Token Exchange
Research note for future implementation
Problem
The /callback?code=... URL is visible in the browser during token refresh. This happens every time tokens need refreshing, not just on initial login. The current implementation appears to re-run the full OIDC redirect flow (prompt=none) instead of using the refresh_token.
Current Behavior
Token expires → Redirect to Authentik (prompt=none) →
Redirect to /callback?code=xxx → Exchange code → Continue
User sees URL flicker to /callback repeatedly.
Desired Behavior
Token expires → Show overlay (lock/lightning icon) →
XHR refresh request → Hide overlay → Continue
No URL changes. No redirects. Just a brief visual indicator.
Key Insight
Only the initial authorization MUST redirect (user needs to see Authentik login UI).
Everything else can be XHR:
| Operation | Current | Should Be |
|---|---|---|
| Initial login | Redirect | Redirect (unavoidable) |
| Token exchange (code → tokens) | Redirect to /callback | XHR POST |
| Token refresh | Full OIDC with prompt=none | XHR POST with refresh_token |
| Session expired | Redirect | Redirect (unavoidable) |
Token Refresh via XHR
final response = await dio.post(
'https://authentik.schweitz.net/application/o/token/',
data: {
'grant_type': 'refresh_token',
'refresh_token': storedRefreshToken,
'client_id': clientId,
},
options: Options(
contentType: Headers.formUrlEncodedContentType,
),
);
// Returns new access_token, refresh_token, expires_in
Potential Blocker: CORS
Authentik's token endpoint may block browser XHR. Solutions:
- Configure Authentik CORS - Allow
home.schweitz.netorigin - Proxy through core-api (recommended)
- Flutter →
POST /auth/refresh→ core-api → Authentik - Keeps client_secret server-side
- No CORS issues
- Flutter →
Implementation Steps
- Verify Authentik is issuing refresh_tokens (check token response)
- Check if refresh_token is being stored (SharedPreferences)
- Test XHR to token endpoint (check CORS)
- If CORS blocked, add
/auth/refreshendpoint to core-api - Refactor
AuthProviderto use XHR refresh instead of full OIDC flow - Add refresh overlay UI (lock icon + brief animation)
- Remove
prompt=noneredirect logic for refresh cases
Files to Investigate
lib/core/auth/auth_provider.dart- Main auth state managementlib/core/auth/oidc_service_web.dart- OIDC implementationlib/core/api/api_interceptors.dart- Token refresh trigger point
References
- CHANGELOG entries v1.1.3-v1.1.6 document the current auth architecture
- AuthController runs in
main()beforerunApp()(v1.1.6 pattern)