Problem: After successful registration, the subsequent login was failing silently, but the error message was misleading and said "Username already taken."
Root Causes:
- Case-sensitive username and email lookups caused false positives
- Username normalization wasn't happening during registration
- Poor error handling in signup flow didn't distinguish between registration and login errors
Fixes Applied:
- ✅ Normalize usernames to lowercase on registration (
api_auth.pyregister endpoint) - ✅ Normalize usernames to lowercase on login (
api_auth.pylogin endpoint) - ✅ Improved error handling in signup page to show specific error messages
- ✅ Split error handling to distinguish registration errors from login errors
Problem: Login was failing even with correct credentials due to case-sensitive username lookups.
Root Causes:
- Username lookup was case-sensitive using
.ilike()inconsistently - Users could enter different case variations of their username
- The username wasn't normalized consistently between registration and login
Fixes Applied:
- ✅ Normalize username input to lowercase before database queries
- ✅ Use exact equality check (==) after normalization instead of
.ilike() - ✅ Separate password verification into its own check for clearer debugging
# REGISTER ENDPOINT
- Normalize username: user_data.username.lower().strip()
- Normalize email: user_data.email.lower().strip()
- Store normalized versions in database
- Better logging with normalized username
# LOGIN ENDPOINT
- Normalize username: form_data.username.lower().strip()
- Use normalized username for exact database lookup
- Separate null check from password verification for better error handling// Improved error handling
- Step 1: Try registration
- Step 2: Try login (with separate error handling)
- Step 3: Get user info and redirect
- Show specific error message for each step- Register with username "TestUser" → should normalize to "testuser"
- Register with same username in different case "TESTUSER" → should fail with "already registered"
- Login with "TestUser" using correct password → should work
- Login with "testuser" using correct password → should work
- Login with wrong password → should show "Incorrect username or password"
- Register with same email in different case → should fail with "already registered"
-
Registration Flow:
User enters: Username="JohnDoe", Email="John@Email.com" ↓ Normalize: username="johndoe", email="john@email.com" ↓ Check if exists (case-insensitive check with ilike) ↓ Store normalized version in database -
Login Flow:
User enters: Username="johndoe", Password="password123" ↓ Normalize: username="johndoe" ↓ Find user with exact match (username="johndoe") ↓ Verify password hash ↓ Return token if successful
- Clear the users table:
DELETE FROM users; - Or normalize existing usernames to lowercase
- Restart the backend
Then users can re-register with their preferred username case.
# Terminal 1: Start backend
cd backend
python -m uvicorn app.main:app --reload
# Terminal 2: Start frontend
cd frontend
npm run dev
# Test in browser:
1. Go to http://localhost:3000/auth/signup
2. Register with any username/email
3. You should be logged in automatically
4. Try logging out and logging back in