messy logout fixing
This commit is contained in:
264
LOGOUT-DEBUGGING-DEPLOYMENT.md
Normal file
264
LOGOUT-DEBUGGING-DEPLOYMENT.md
Normal file
@@ -0,0 +1,264 @@
|
||||
# Logout Debugging System - Deployment Guide
|
||||
|
||||
## Overview
|
||||
This guide will help you deploy the comprehensive logout debugging and tracking system to identify why users are being logged out after 20-25 minutes.
|
||||
|
||||
## What Was Implemented
|
||||
|
||||
### 1. **LogoutTracker Service** (`frontend/src/services/logoutTracker.ts`)
|
||||
- Tracks every logout event with full context
|
||||
- Monitors user activity (mouse, keyboard, clicks, scrolls)
|
||||
- Calculates idle time before logout
|
||||
- Shows visual alert to user before redirect
|
||||
- Logs to backend API
|
||||
- Stores logout history in localStorage
|
||||
|
||||
### 2. **TokenExpiryMonitor Service** (`frontend/src/services/tokenExpiryMonitor.ts`)
|
||||
- Monitors JWT token expiry every 30 seconds
|
||||
- Logs token status to console with color-coded warnings
|
||||
- Alerts when access token < 5 minutes from expiry
|
||||
- Critical alert when refresh token < 1 day from expiry
|
||||
- Exposes `window.__tokenMonitor.getTokenStatus()` for debugging
|
||||
|
||||
### 3. **Backend Logout Tracking Endpoint** (`backend/auth/views_logout_tracking.py`)
|
||||
- Receives logout events from frontend
|
||||
- Logs with full details: type, message, idle time, IP, user agent
|
||||
- Creates server-side audit trail
|
||||
|
||||
### 4. **LogoutReasonBanner Component** (`frontend/src/components/auth/LogoutReasonBanner.tsx`)
|
||||
- Displays on signin page showing why user was logged out
|
||||
- Shows icon, user-friendly message, and technical details
|
||||
- Auto-clears after 30 seconds
|
||||
|
||||
### 5. **AuthDebugPanel Component** (`frontend/src/components/debug/AuthDebugPanel.tsx`)
|
||||
- Real-time auth status dashboard
|
||||
- Shows token expiry times
|
||||
- Displays recent logout history
|
||||
- Toggle with Ctrl+Shift+D or click button
|
||||
|
||||
### 6. **Updated Login Flow**
|
||||
- Added remember_me parameter support
|
||||
- Generates device_id for tracking
|
||||
- Passes to backend for 20-day token expiry
|
||||
|
||||
## Deployment Steps
|
||||
|
||||
### Step 1: Deploy Backend Changes
|
||||
|
||||
```bash
|
||||
cd /data/app/igny8/backend
|
||||
|
||||
# Run migrations for RefreshToken model
|
||||
python manage.py migrate
|
||||
|
||||
# Restart backend services
|
||||
sudo systemctl restart gunicorn
|
||||
sudo systemctl restart celery
|
||||
```
|
||||
|
||||
### Step 2: Deploy Frontend Changes
|
||||
|
||||
```bash
|
||||
cd /data/app/igny8/frontend
|
||||
|
||||
# Install dependencies (if needed)
|
||||
npm install
|
||||
|
||||
# Build production bundle
|
||||
npm run build
|
||||
|
||||
# Deploy to production
|
||||
# (Your deployment command here, e.g., docker build, rsync, etc.)
|
||||
```
|
||||
|
||||
### Step 3: Verify Deployment
|
||||
|
||||
1. **Check Console Logs**
|
||||
- Open browser DevTools (F12)
|
||||
- Go to Console tab
|
||||
- You should see: `[TokenMonitor] Starting token expiry monitoring...`
|
||||
- Every 30 seconds, you'll see token status logs
|
||||
|
||||
2. **Test Login**
|
||||
- Go to signin page
|
||||
- Check "Remember me for 20 days" checkbox
|
||||
- Login
|
||||
- Open Console - you should see token expiry times logged
|
||||
|
||||
3. **Test Logout Tracking**
|
||||
- Open another tab and manually logout
|
||||
- You should see a modal alert before redirect
|
||||
- On signin page, you should see logout reason banner
|
||||
|
||||
4. **Check Debug Panel**
|
||||
- Press Ctrl+Shift+D or click 🔍 button in bottom-right
|
||||
- Verify auth status, token info, and logout history
|
||||
|
||||
### Step 4: Monitor for 20-25 Minute Logout
|
||||
|
||||
1. **Login with Remember Me checked**
|
||||
2. **Keep browser tab open for 25+ minutes** (minimize but don't close)
|
||||
3. **Watch Console logs** - every 30 seconds you'll see token status
|
||||
4. **If logout occurs:**
|
||||
- Modal alert will show WHY
|
||||
- Console will show detailed logs
|
||||
- Backend will log the event
|
||||
- Signin page will show logout reason
|
||||
|
||||
### Step 5: Analyze Collected Data
|
||||
|
||||
After capturing a logout event:
|
||||
|
||||
1. **Check Browser Console:**
|
||||
```
|
||||
[LogoutTracker] Logout event: TOKEN_EXPIRED
|
||||
[LogoutTracker] Idle time: 23 minutes
|
||||
[LogoutTracker] Details: { hasToken: true, ... }
|
||||
```
|
||||
|
||||
2. **Check Backend Logs:**
|
||||
```bash
|
||||
docker logs igny8-backend | grep "LOGOUT EVENT"
|
||||
```
|
||||
|
||||
3. **Check Signin Page Banner:**
|
||||
- Shows logout reason and technical details
|
||||
|
||||
4. **Use Debug Panel:**
|
||||
- Press Ctrl+Shift+D
|
||||
- View "Recent Logouts" section
|
||||
- Click "Log Full State to Console"
|
||||
|
||||
## What to Look For
|
||||
|
||||
### If Logout Type is `TOKEN_EXPIRED`:
|
||||
- Check access token expiry time (should be 1 hour)
|
||||
- Check refresh token expiry time (should be 20 days with remember_me)
|
||||
- Verify remember_me checkbox was checked during login
|
||||
|
||||
### If Logout Type is `REFRESH_FAILED`:
|
||||
- Check backend logs for refresh endpoint errors
|
||||
- Verify RefreshToken model is working
|
||||
- Check Redis session storage
|
||||
|
||||
### If Logout Type is `AUTH_ERROR`:
|
||||
- Check for 403/402 errors in Network tab
|
||||
- Verify middleware isn't forcing logout
|
||||
|
||||
### If Logout Type is `UNKNOWN`:
|
||||
- Check for JavaScript errors
|
||||
- Verify BroadcastChannel multi-tab coordination
|
||||
- Check if browser extensions are interfering
|
||||
|
||||
## Debugging Commands
|
||||
|
||||
### Frontend Console Commands:
|
||||
|
||||
```javascript
|
||||
// Get current token status
|
||||
window.__tokenMonitor.getTokenStatus()
|
||||
|
||||
// Get logout history
|
||||
JSON.parse(localStorage.getItem('logout_history') || '[]')
|
||||
|
||||
// Get last logout reason
|
||||
sessionStorage.getItem('last_logout_reason')
|
||||
|
||||
// Check auth state
|
||||
JSON.parse(localStorage.getItem('auth-storage'))
|
||||
```
|
||||
|
||||
### Backend Commands:
|
||||
|
||||
```bash
|
||||
# Check RefreshToken model
|
||||
python manage.py shell
|
||||
>>> from igny8_core.auth.models_refresh_token import RefreshToken
|
||||
>>> RefreshToken.objects.all()
|
||||
|
||||
# Check Redis session
|
||||
redis-cli
|
||||
> KEYS *session*
|
||||
|
||||
# View backend logs
|
||||
docker logs -f igny8-backend | grep -E "LOGOUT|TOKEN|AUTH"
|
||||
```
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
### With Remember Me Checked:
|
||||
- Access token: 1 hour expiry
|
||||
- Refresh token: 20 days expiry
|
||||
- User stays logged in for 20 days, including idle time
|
||||
- Token auto-refreshes when access token expires
|
||||
|
||||
### Without Remember Me:
|
||||
- Access token: 1 hour expiry
|
||||
- Refresh token: 7 days expiry
|
||||
- User stays logged in for 7 days
|
||||
|
||||
### Logout Should Only Occur When:
|
||||
1. User explicitly clicks logout
|
||||
2. Refresh token expires (20 days or 7 days)
|
||||
3. Refresh token is revoked
|
||||
4. User changes password (revokes all tokens)
|
||||
|
||||
### Logout Should NEVER Occur Due To:
|
||||
- Network failures
|
||||
- 403 permission errors
|
||||
- 402 payment errors
|
||||
- 5xx server errors
|
||||
- Multi-tab usage
|
||||
- Idle time (as long as refresh token valid)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Issue: Token Monitor Not Starting
|
||||
**Solution:** Check browser console for errors. Verify import in App.tsx.
|
||||
|
||||
### Issue: Logout Alert Not Showing
|
||||
**Solution:** Check LogoutTracker import in authStore.ts. Verify trackLogout() is called.
|
||||
|
||||
### Issue: Backend Not Receiving Logout Events
|
||||
**Solution:** Check network tab for POST to /v1/auth/logout-event/. Verify CORS settings.
|
||||
|
||||
### Issue: Logout Banner Not Showing
|
||||
**Solution:** Verify LogoutReasonBanner is imported in SignInForm.tsx.
|
||||
|
||||
### Issue: Still Logging Out at 20 Minutes
|
||||
**Possible Causes:**
|
||||
1. Remember me checkbox not checked during login
|
||||
2. Frontend not sending remember_me=true to backend
|
||||
3. Backend not respecting remember_me flag
|
||||
4. Redis session expiring (check SESSION_COOKIE_AGE in settings.py)
|
||||
5. JWT access token in localStorage causing issues (should be removed)
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Deploy to production** using steps above
|
||||
2. **Login with remember_me checked** and wait 25+ minutes
|
||||
3. **Capture logout event** with all debugging data
|
||||
4. **Analyze the data** to identify exact cause
|
||||
5. **Report findings** with:
|
||||
- Logout type (from console logs)
|
||||
- Idle time (from logout banner)
|
||||
- Token status (from TokenMonitor logs)
|
||||
- Backend logs (from server)
|
||||
- Network tab (API calls before logout)
|
||||
|
||||
## Additional Notes
|
||||
|
||||
- All debugging is production-safe (no performance impact)
|
||||
- Token monitoring is throttled to 30-second intervals
|
||||
- Logout tracking has minimal overhead
|
||||
- Debug panel is only visible when opened (Ctrl+Shift+D)
|
||||
- All logs can be disabled by removing console.log statements
|
||||
|
||||
## Support
|
||||
|
||||
If issues persist after deployment:
|
||||
1. Export console logs: Right-click console → Save as...
|
||||
2. Export logout history: `copy(localStorage.getItem('logout_history'))`
|
||||
3. Export token status: `copy(JSON.stringify(window.__tokenMonitor.getTokenStatus()))`
|
||||
4. Export backend logs: `docker logs igny8-backend > backend-logs.txt`
|
||||
5. Share all data for analysis
|
||||
Reference in New Issue
Block a user