149 lines
4.1 KiB
Markdown
149 lines
4.1 KiB
Markdown
# Authentication Error Fix Guide
|
|
|
|
## Problem
|
|
|
|
**Error Message**: `Authentication failed: Unexpected token '<', "<!DOCTYPE "... is not valid JSON`
|
|
|
|
**What This Means**: The frontend JavaScript is trying to call authentication endpoints (`/auth/status`, `/auth/login`) but instead of receiving JSON responses, it's receiving HTML (the web UI page). When JavaScript tries to parse this HTML as JSON, it fails with this error.
|
|
|
|
## Root Cause
|
|
|
|
This is a known Apache ProxyPass issue (documented in CLAUDE.md Issue 2):
|
|
|
|
1. Your application is served through Apache proxy at: `https://ai-sandbox.oliver.solutions/ai_qc/`
|
|
2. Apache is configured with ProxyPass rules to forward requests to Flask on `localhost:7183`
|
|
3. **BUT**: Apache checks for static files/directories BEFORE applying ProxyPass rules
|
|
4. If a directory `/var/www/html/ai_qc/` exists, Apache tries to serve files from there instead
|
|
5. Result: Authentication endpoints return the static `index.html` (or web_ui.html) instead of JSON
|
|
|
|
## Solution
|
|
|
|
### Quick Fix (On Production Server)
|
|
|
|
```bash
|
|
# 1. Upload diagnostic script to production server
|
|
scp diagnose_auth_issue.sh user@ai-sandbox.oliver.solutions:/tmp/
|
|
|
|
# 2. SSH into production server
|
|
ssh user@ai-sandbox.oliver.solutions
|
|
|
|
# 3. Run diagnostic
|
|
bash /tmp/diagnose_auth_issue.sh
|
|
|
|
# 4. If it shows a conflicting directory, run the fix
|
|
sudo bash /tmp/fix_apache_proxy.sh
|
|
```
|
|
|
|
### Manual Fix Steps
|
|
|
|
If you prefer to fix manually:
|
|
|
|
1. **Check for conflicting directory:**
|
|
```bash
|
|
ls -la /var/www/html/ai_qc/
|
|
```
|
|
|
|
2. **If it exists, back it up and remove:**
|
|
```bash
|
|
sudo mv /var/www/html/ai_qc /var/www/html/ai_qc.backup.$(date +%Y%m%d_%H%M%S)
|
|
```
|
|
|
|
3. **Verify Apache ProxyPass configuration:**
|
|
```bash
|
|
sudo grep -A5 "ai_qc" /etc/apache2/apache2.conf
|
|
# OR
|
|
sudo grep -A5 "ai_qc" /etc/apache2/sites-enabled/*
|
|
```
|
|
|
|
Should contain:
|
|
```apache
|
|
# More specific paths first
|
|
ProxyPass /ai_qc/auth http://localhost:7183/auth
|
|
ProxyPassReverse /ai_qc/auth http://localhost:7183/auth
|
|
|
|
# General path last
|
|
ProxyPass /ai_qc http://localhost:7183
|
|
ProxyPassReverse /ai_qc http://localhost:7183
|
|
```
|
|
|
|
4. **Restart Apache:**
|
|
```bash
|
|
sudo systemctl restart apache2
|
|
```
|
|
|
|
5. **Test the fix:**
|
|
```bash
|
|
# Should return JSON with authentication status
|
|
curl https://ai-sandbox.oliver.solutions/ai_qc/auth/status
|
|
|
|
# Should NOT return HTML starting with <!DOCTYPE
|
|
```
|
|
|
|
## Verification
|
|
|
|
After applying the fix, verify in your browser:
|
|
|
|
1. Open https://ai-sandbox.oliver.solutions/ai_qc/ in a **new incognito/private window** (to avoid cache)
|
|
2. Open browser console (F12)
|
|
3. Look for console messages about authentication
|
|
4. Try signing in with Microsoft
|
|
5. Should work without the JSON parsing error
|
|
|
|
## If Still Not Working
|
|
|
|
Check these:
|
|
|
|
### 1. Backend Status
|
|
```bash
|
|
# Check if Flask is running
|
|
sudo systemctl status ai_qc.service
|
|
|
|
# Check Flask logs for errors
|
|
sudo journalctl -u ai_qc.service -f
|
|
```
|
|
|
|
### 2. Apache Logs
|
|
```bash
|
|
# Check Apache error logs
|
|
sudo tail -f /var/log/apache2/ai_qc_ssl_error.log
|
|
|
|
# Check access patterns
|
|
sudo tail -f /var/log/apache2/ai_qc_ssl_access.log
|
|
```
|
|
|
|
### 3. Direct Backend Test
|
|
```bash
|
|
# Test backend directly (should work)
|
|
curl -I http://localhost:7183/auth/status
|
|
|
|
# Test through Apache proxy (should also work after fix)
|
|
curl -I https://ai-sandbox.oliver.solutions/ai_qc/auth/status
|
|
```
|
|
|
|
### 4. Browser Console
|
|
- Open F12 Developer Tools
|
|
- Go to Network tab
|
|
- Try signing in
|
|
- Look at the `/auth/status` request
|
|
- Check if it's returning HTML or JSON
|
|
|
|
## Why This Happens
|
|
|
|
Apache's request handling order:
|
|
1. Check for static files/directories
|
|
2. Apply rewrite rules
|
|
3. **Then** apply ProxyPass rules ← This is where our backend should handle it
|
|
|
|
If a static directory exists at step 1, Apache never reaches step 3!
|
|
|
|
## Prevention
|
|
|
|
When using Apache ProxyPass:
|
|
- **DO NOT** create a static directory that matches your proxy path
|
|
- All content should be served through the Flask backend via proxy
|
|
- The backend serves the web UI HTML and handles all API endpoints
|
|
|
|
## Related Documentation
|
|
|
|
- See `CLAUDE.md` → "Production Deployment" → "Issue 2: Apache ProxyPass Not Working"
|
|
- See production deployment checklist in `CLAUDE.md`
|