auth refactor plan for later consideration
This commit is contained in:
@@ -0,0 +1,86 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
```dart
|
||||||
|
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:
|
||||||
|
|
||||||
|
1. **Configure Authentik CORS** - Allow `home.schweitz.net` origin
|
||||||
|
2. **Proxy through core-api** (recommended)
|
||||||
|
- Flutter → `POST /auth/refresh` → core-api → Authentik
|
||||||
|
- Keeps client_secret server-side
|
||||||
|
- No CORS issues
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
|
||||||
|
1. [ ] Verify Authentik is issuing refresh_tokens (check token response)
|
||||||
|
2. [ ] Check if refresh_token is being stored (SharedPreferences)
|
||||||
|
3. [ ] Test XHR to token endpoint (check CORS)
|
||||||
|
4. [ ] If CORS blocked, add `/auth/refresh` endpoint to core-api
|
||||||
|
5. [ ] Refactor `AuthProvider` to use XHR refresh instead of full OIDC flow
|
||||||
|
6. [ ] Add refresh overlay UI (lock icon + brief animation)
|
||||||
|
7. [ ] Remove `prompt=none` redirect logic for refresh cases
|
||||||
|
|
||||||
|
## Files to Investigate
|
||||||
|
|
||||||
|
- `lib/core/auth/auth_provider.dart` - Main auth state management
|
||||||
|
- `lib/core/auth/oidc_service_web.dart` - OIDC implementation
|
||||||
|
- `lib/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()` before `runApp()` (v1.1.6 pattern)
|
||||||
Reference in New Issue
Block a user