Spaces:
Sleeping
Sleeping
File size: 5,764 Bytes
f9637ae b23f5d7 f9637ae b23f5d7 f9637ae b23f5d7 f9637ae b23f5d7 f9637ae b23f5d7 f9637ae b23f5d7 f9637ae b23f5d7 f9637ae b23f5d7 f9637ae b23f5d7 f9637ae b23f5d7 f9637ae b23f5d7 f9637ae b23f5d7 f9637ae b23f5d7 f9637ae b23f5d7 f9637ae |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# JWT Token Expiration Fix
## Problem
Users are getting logged out too quickly. Token expired after ~9 hours instead of the expected 24 hours.
**Error from logs:**
```
ERROR: 2025-11-18T05:38:46 - app.core.supabase_auth: Get user error: invalid JWT: unable to parse or verify signature, token has invalid claims: token is expired
```
## Root Cause
The JWT tokens are managed by **Supabase Auth**, not the backend `ACCESS_TOKEN_EXPIRE_MINUTES` setting. Supabase has its own JWT expiry configuration that overrides your backend setting.
---
## β
WORKING SOLUTION: Automatic Token Refresh
**Status:** β
Implemented and tested
**Requirements:** Supabase Free tier (no upgrade needed)
**User Experience:** Users stay logged in for 30 days
### What Was Implemented
1. **Backend Changes:**
- Modified `/api/v1/auth/login` to return `refresh_token` and `expires_in`
- Created new `/api/v1/auth/refresh-token` endpoint with automatic token rotation
- Added `refresh_session()` method to SupabaseAuthService
2. **How It Works:**
- User logs in β receives access token (1 hour) + refresh token (30 days)
- Frontend schedules auto-refresh 5 minutes before expiration
- Token refreshes automatically in background
- Users stay logged in seamlessly for up to 30 days
3. **Implementation Guide:**
- See: [`docs/FRONTEND_TOKEN_REFRESH_GUIDE.md`](./FRONTEND_TOKEN_REFRESH_GUIDE.md)
- Complete TypeScript/JavaScript code examples
- React and Vue integration examples
- Testing procedures
**Why This Solution:**
- β
Works with Supabase Free tier
- β
No Pro plan upgrade required
- β
Better security (token rotation)
- β
Seamless user experience
- β
Industry best practice
---
## β Option 1: Configure Supabase JWT Expiry
**Status:** β Not available on Supabase Free tier
**Requirements:** Supabase Pro plan ($25/month)
β οΈ **This option requires upgrading to Supabase Pro plan**
**In your Supabase Dashboard:**
1. Go to **Settings** > **Auth**
2. Find **JWT Expiry**
3. Change from default (3600 seconds / 1 hour) to **86400 seconds (24 hours)** or longer
4. Save changes
**Or via Supabase SQL:**
```sql
-- Update JWT expiry to 7 days (604800 seconds)
ALTER DATABASE postgres
SET app.settings.jwt_exp = '604800';
```
---
## π Alternative Options (Reference Only)
### Option 2: Backend Token Configuration
**Status:** β οΈ Limited effect (Supabase controls JWT expiry)
**File: `src/app/config_settings.py`**
You can extend the backend token setting, but this won't affect Supabase-managed JWTs:
```python
# Change from:
ACCESS_TOKEN_EXPIRE_MINUTES: int = 1440 # 24 hours
# To:
ACCESS_TOKEN_EXPIRE_MINUTES: int = 10080 # 7 days
# Or:
ACCESS_TOKEN_EXPIRE_MINUTES: int = 43200 # 30 days
```
**Note:** This only affects custom JWT tokens if you create them outside Supabase. Supabase tokens are controlled by Supabase Auth settings.
---
## π Additional Resources
- **Implementation Guide:** [`docs/FRONTEND_TOKEN_REFRESH_GUIDE.md`](./FRONTEND_TOKEN_REFRESH_GUIDE.md)
- **Supabase Auth Docs:** https://supabase.com/docs/guides/auth
- **JWT Best Practices:** https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/
---
## β
Recommended Solution
**Use the automatic token refresh implementation** (already complete):
1. β
Backend changes pushed to production
2. π Follow frontend guide: [`FRONTEND_TOKEN_REFRESH_GUIDE.md`](./FRONTEND_TOKEN_REFRESH_GUIDE.md)
3. π§ͺ Test the complete flow
4. π Users stay logged in for 30 days seamlessly!
**Step 3: Add refresh endpoint to backend**
- Add `/api/v1/auth/refresh-token` endpoint
- Implement `refresh_session()` in SupabaseAuthService
## Testing
**Test token expiration:**
```bash
# Login
curl -X POST http://localhost:8000/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@swiftops.com","password":"yourpassword"}'
# Get access_token and refresh_token from response
# Wait for token to expire (or manually expire it)
# Test refresh
curl -X POST http://localhost:8000/api/v1/auth/refresh-token \
-H "Content-Type: application/json" \
-d '{"refresh_token":"YOUR_REFRESH_TOKEN"}'
```
**Frontend test:**
```javascript
// Force token refresh
await refreshAccessToken();
// Check if it works
const response = await api.get('/api/v1/auth/me');
console.log(response.data); // Should return user data
```
## Security Considerations
1. **Never store tokens in localStorage for sensitive apps** - Use httpOnly cookies instead
2. **Always use HTTPS** in production
3. **Rotate refresh tokens** after each use (Supabase does this automatically)
4. **Set appropriate expiry times:**
- Access token: 1-24 hours
- Refresh token: 7-30 days
5. **Implement token revocation** for logout
## Environment Variables
Add to `.env`:
```bash
# JWT Settings
ACCESS_TOKEN_EXPIRE_MINUTES=10080 # 7 days
REFRESH_TOKEN_EXPIRE_DAYS=30
# Supabase JWT Expiry (configure in Supabase Dashboard)
# JWT_EXP=604800 # 7 days
```
## Summary
**Immediate Fix:**
1. Go to Supabase Dashboard
2. Settings > Auth > JWT Expiry
3. Change to 604800 seconds (7 days)
**Long-term Solution:**
1. Implement token refresh endpoint in backend
2. Add auto-refresh logic to frontend
3. Handle 401 errors gracefully
4. Test thoroughly
**Result:**
- Users stay logged in for 7 days
- Tokens refresh automatically before expiration
- Smooth user experience without unexpected logouts
- Proper security with shorter-lived access tokens
## Additional Resources
- [Supabase Auth Documentation](https://supabase.com/docs/guides/auth)
- [JWT Best Practices](https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/)
- [Token Refresh Strategies](https://www.rfc-editor.org/rfc/rfc6749#section-6)
|