# Authentication Quick Reference
## For Backend Developers
### Protecting a Route
```python
from flask import Blueprint
from server.permissions import require_role, admin_or_higher, editor_or_higher
my_bp = Blueprint("myroute", __name__, url_prefix="/api/myroute")
# Specific role(s)
@my_bp.route("/admin")
@require_role('admin', 'superadmin')
def admin_only():
return {"message": "Admin only"}
# Convenience decorators
@my_bp.route("/settings")
@admin_or_higher
def settings():
return {"message": "Admin or superadmin"}
@my_bp.route("/create", methods=["POST"])
@editor_or_higher
def create():
return {"message": "Editor, admin, or superadmin"}
```
### Getting Current User in Route
```python
from flask import session
@my_bp.route("/profile")
@require_auth
def profile():
user_id = session.get('user_id')
username = session.get('username')
role = session.get('role')
return {
"user_id": user_id,
"username": username,
"role": role
}
```
## For Frontend Developers
### Using the Auth Hook
```typescript
import { useAuth } from './useAuth';
function MyComponent() {
const { user, isAuthenticated, login, logout, loading } = useAuth();
if (loading) return
Loading...
;
if (!isAuthenticated) {
return ;
}
return (
Welcome {user?.username}
Role: {user?.role}
);
}
```
### Conditional Rendering
```typescript
import { useCurrentUser } from './useAuth';
import { isAdminOrHigher, isEditorOrHigher } from './apiAuth';
function Navigation() {
const user = useCurrentUser();
return (
);
}
```
### Making Authenticated API Calls
```typescript
// Always include credentials for session cookies
const response = await fetch('/api/protected-route', {
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
// ... other options
});
```
## Role Hierarchy
```
superadmin > admin > editor > user
```
| Role | Can Do |
|------|--------|
| **user** | View events |
| **editor** | user + CRUD events/media |
| **admin** | editor + manage users/groups/settings |
| **superadmin** | admin + manage superadmins + system config |
## Environment Variables
```bash
# Required for sessions
FLASK_SECRET_KEY=your_secret_key_here
# Required for superadmin creation
DEFAULT_SUPERADMIN_USERNAME=superadmin
DEFAULT_SUPERADMIN_PASSWORD=your_password_here
```
Generate a secret key:
```bash
python -c 'import secrets; print(secrets.token_hex(32))'
```
## Testing Endpoints
```bash
# Login
curl -X POST http://localhost:8000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"superadmin","password":"your_password"}' \
-c cookies.txt
# Check current user
curl http://localhost:8000/api/auth/me -b cookies.txt
# Check auth status (lightweight)
curl http://localhost:8000/api/auth/check -b cookies.txt
# Logout
curl -X POST http://localhost:8000/api/auth/logout -b cookies.txt
# Test protected route
curl http://localhost:8000/api/protected -b cookies.txt
```
## Common Patterns
### Backend: Optional Auth
```python
from flask import session
@my_bp.route("/public-with-extras")
def public_route():
user_id = session.get('user_id')
if user_id:
# Show extra content for authenticated users
return {"data": "...", "extras": "..."}
else:
# Public content only
return {"data": "..."}
```
### Frontend: Redirect After Login
```typescript
const { login } = useAuth();
const handleLogin = async (username: string, password: string) => {
try {
await login(username, password);
window.location.href = '/dashboard';
} catch (err) {
console.error('Login failed:', err);
}
};
```
### Frontend: Protected Route Component
```typescript
import { useAuth } from './useAuth';
import { Navigate } from 'react-router-dom';
function ProtectedRoute({ children }: { children: React.ReactNode }) {
const { isAuthenticated, loading } = useAuth();
if (loading) return
Loading...
;
if (!isAuthenticated) {
return ;
}
return <>{children}>;
}
// Usage in routes:
} />
```
## Troubleshooting
### "Authentication required" on /api/auth/me
✅ **Normal** - User is not logged in. This is expected behavior.
### Session not persisting across requests
- Check `credentials: 'include'` in fetch calls
- Verify `FLASK_SECRET_KEY` is set
- Check browser cookies are enabled
### 403 Forbidden on decorated route
- Verify user is logged in
- Check user role matches required role
- Inspect response for `required_roles` and `your_role`
## Files Reference
| File | Purpose |
|------|---------|
| `server/routes/auth.py` | Auth endpoints (login, logout, /me) |
| `server/permissions.py` | Permission decorators |
| `dashboard/src/apiAuth.ts` | Frontend API client |
| `dashboard/src/useAuth.tsx` | React context/hooks |
| `models/models.py` | User model and UserRole enum |
## Full Documentation
See `AUTH_SYSTEM.md` for complete documentation including:
- Architecture details
- Security considerations
- API reference
- Testing guide
- Production checklist