mirror of
https://gitea.tendokyu.moe/pinapelz/Mirage.git
synced 2026-09-27 09:23:22 +03:00
5.4 KiB
5.4 KiB
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
- Copy
.env.exampleto.env:
cp .env.example .env
- Update the
SESSION_SECRETin your.envfile 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:
// 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
// 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
// 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
// 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:
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
SESSION_SECRET="your-production-secret-minimum-32-characters-long"
NODE_ENV="production"
FRONTEND_URL="https://yourdomain.com"
Security Settings
In production, ensure:
SESSION_SECRETis a strong, unique stringsecure: truein cookie settings (HTTPS only)- Proper CORS origin configuration
- 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
- Session not persisting: Make sure
credentials: 'include'is set in frontend requests - CORS errors: Verify CORS origin matches your frontend URL
- Session expires immediately: Check system time and session expiration settings
- Authentication fails after server restart: Sessions are stored in database, so they should persist
Debug Session Issues
Check session status:
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:
DELETE FROM Session;
Database Schema
The session system adds a Session table:
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.