Files
pinapelz_Mirage/docs/SESSION_GUIDE.md
T

221 lines
5.4 KiB
Markdown

# Session Management Guide
This guide explains how to use the session-based authentication system implemented in the backend.
## Overview
The backend now supports persistent login sessions using:
- **express-session** for server-side session management
- **HTTP-only cookies** for secure session storage
- **Database session tracking** with automatic cleanup
- **CSRF protection** through HTTP-only cookies
## Environment Setup
1. Copy `.env.example` to `.env`:
```bash
cp .env.example .env
```
2. Update the `SESSION_SECRET` in your `.env` file with a secure random string:
```
SESSION_SECRET="your-very-secure-secret-key-change-this-in-production-make-it-long-and-random"
```
## API Endpoints
### Authentication Endpoints
#### Register User
- **POST** `/api/register`
- **Body**: `{ username, password, name, email }`
- **Response**: User data + session created
- **Sets**: HTTP-only session cookie
#### Login
- **POST** `/api/authenticate`
- **Body**: `{ username, password }`
- **Response**: User data + session created
- **Sets**: HTTP-only session cookie
#### Logout
- **POST** `/api/logout`
- **Requires**: Valid session
- **Response**: Success message
- **Clears**: Session cookie and database sessions
### Session Management
#### Check Session Status
- **GET** `/api/session`
- **Response**: `{ authenticated: boolean, user?: UserData }`
- **Use**: Check if user is still logged in
#### Get Current User
- **GET** `/api/me`
- **Requires**: Valid session
- **Response**: Current user data
## Frontend Integration
### Making Authenticated Requests
Always include credentials in your fetch requests:
```javascript
// Example fetch with credentials
const response = await fetch('http://localhost:5000/api/me', {
method: 'GET',
credentials: 'include', // This is crucial!
headers: {
'Content-Type': 'application/json',
}
});
```
### Login Flow Example
```javascript
// Login
const loginResponse = await fetch('http://localhost:5000/api/authenticate', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: 'user@example.com',
password: 'password123'
})
});
if (loginResponse.ok) {
const userData = await loginResponse.json();
console.log('Logged in:', userData);
// Session cookie is automatically set
}
```
### Check Authentication Status
```javascript
// Check if user is still logged in
const sessionResponse = await fetch('http://localhost:5000/api/session', {
method: 'GET',
credentials: 'include'
});
const sessionData = await sessionResponse.json();
if (sessionData.authenticated) {
console.log('User is logged in:', sessionData.user);
} else {
console.log('User is not logged in');
}
```
### Logout
```javascript
// Logout
const logoutResponse = await fetch('http://localhost:5000/api/logout', {
method: 'POST',
credentials: 'include'
});
if (logoutResponse.ok) {
console.log('Logged out successfully');
// Session cookie is automatically cleared
}
```
## Security Features
### Session Security
- **HTTP-only cookies**: Prevents XSS attacks
- **Secure cookies**: Enabled in production (HTTPS)
- **SameSite protection**: Prevents CSRF attacks
- **Session expiration**: 24-hour automatic expiry
### Database Sessions
- Sessions are stored in the database for server-side validation
- Expired sessions are automatically cleaned up every hour
- User logout removes all sessions for that user
### Password Security
- Passwords are hashed with bcrypt (12 rounds)
- Unique salt per user for additional security
- Original password never stored
## Middleware
### `requireAuth` Middleware
Protects routes that need authentication:
```javascript
app.get('/api/protected-route', requireAuth, (req, res) => {
// req.user contains the authenticated user data
const user = req.user;
res.json({ message: 'This is protected', user });
});
```
## Production Considerations
### Environment Variables
```env
SESSION_SECRET="your-production-secret-minimum-32-characters-long"
NODE_ENV="production"
FRONTEND_URL="https://yourdomain.com"
```
### Security Settings
In production, ensure:
1. `SESSION_SECRET` is a strong, unique string
2. `secure: true` in cookie settings (HTTPS only)
3. Proper CORS origin configuration
4. HTTPS enabled for your domain
### Database
- Consider using PostgreSQL or MySQL instead of SQLite
- Implement database connection pooling
- Set up database backups
## Troubleshooting
### Common Issues
1. **Session not persisting**: Make sure `credentials: 'include'` is set in frontend requests
2. **CORS errors**: Verify CORS origin matches your frontend URL
3. **Session expires immediately**: Check system time and session expiration settings
4. **Authentication fails after server restart**: Sessions are stored in database, so they should persist
### Debug Session Issues
Check session status:
```javascript
fetch('http://localhost:5000/api/session', {
credentials: 'include'
}).then(r => r.json()).then(console.log);
```
### Clear All Sessions
If you need to force logout all users:
```sql
DELETE FROM Session;
```
## Database Schema
The session system adds a `Session` table:
```prisma
model Session {
id String @id @default(cuid())
userId Int
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
expiresAt DateTime
}
```
Sessions are automatically linked to users and cleaned up when users are deleted.