# Feladat Leírás ## 🎯 Cél Implementálj egy teljes authentication és authorization rendszert egy blog platformhoz JWT token használatával, cookie-alapú session kezeléssel. --- ## ⚠️ MIT KELL IMPLEMENTÁLNI ### 1. AuthController (`src/api/controllers/AuthController.js`) #### `register(req, res)` ✏️ ```javascript // Input: { email, username, password } // 1. Validálás (kötelező mezők, formátum) // 2. Ellenőrizd: email és username unique? // 3. Hash-eld a jelszót: bcrypt.hash(password, 10) // 4. Hozd létre a user-t: userRepository.create() // 5. Generálj JWT tokent: jwt.sign() // 6. Állíts be HTTP-only cookie-t: res.cookie() // 7. Válasz: { user (jelszó nélkül!), accessToken, refreshToken } ``` #### `login(req, res)` ✏️ ```javascript // Input: { email vagy username, password } // 1. Keresd meg a user-t: userRepository.findByEmail() vagy findByUsername() // 2. Ha nincs user → 401 error // 3. Ellenőrizd a jelszót: bcrypt.compare(password, user.password) // 4. Ha nem egyezik → 401 error // 5. Generálj access és refresh tokent // 6. Állítsd be a cookie-kat // 7. Redis session (opcionális): redis.set(`session:${userId}`, ...) // 8. Válasz: { user, accessToken, refreshToken } ``` #### `logout(req, res)` ✏️ ```javascript // 1. Töröld a cookie-kat: res.clearCookie('accessToken') // 2. Redis session törlés: redis.del(`session:${userId}`) // 3. Válasz: { success: true, message: 'Logged out' } ``` #### `refreshToken(req, res)` ✏️ ```javascript // 1. Olvasd ki a refresh tokent: req.cookies.refreshToken // 2. Validáld: jwt.verify(refreshToken, JWT_REFRESH_SECRET) // 3. Generálj új access tokent // 4. Állítsd be az új cookie-t // 5. Válasz: { accessToken } ``` #### `getCurrentUser(req, res)` ✏️ ```javascript // 1. req.user-ből olvasd ki a user adatokat // 2. Válasz: { user } ``` --- ### 2. AuthMiddleware (`src/api/middlewares/authMiddleware.js`) #### `authenticateToken(req, res, next)` ✏️ ```javascript // 1. Token kiolvasás: // - Cookie-ból: req.cookies.accessToken // - VAGY Header-ből: req.headers.authorization (Bearer token) // 2. Ha nincs token → 401 Unauthorized // 3. Validálás: jwt.verify(token, JWT_SECRET) // 4. User lekérés: userRepository.findById(decoded.userId) // 5. req.user = user // 6. next() ``` #### `requireRole(allowedRoles)` ✏️ ```javascript // Higher-order function - visszaad egy middleware-t return (req, res, next) => { // 1. Ellenőrizd: req.user létezik? // 2. Ellenőrizd: allowedRoles.includes(req.user.role)? // 3. Ha nem → 403 Forbidden // 4. Ha yes → next() } // Használat: // router.delete('/admin', authenticateToken, requireRole(['ADMIN']), ...) ``` #### `checkOwnership(getResourceOwnerId)` ✏️ ```javascript // Higher-order function return async (req, res, next) => { // 1. Szerezd meg a resource owner ID-t: // const ownerId = await getResourceOwnerId(req) // 2. Ellenőrizd: req.user.id === ownerId VAGY req.user.role === 'ADMIN' // 3. Ha nem → 403 Forbidden // 4. Ha yes → next() } // Használat: // router.put('/blogs/:id', authenticateToken, // checkOwnership(async (req) => { // const blog = await blogRepository.findById(req.params.id); // return blog.authorId; // }), // updateController // ); ``` --- ### 3. Route-ok védelme #### `src/api/routes/authRoutes.js` ✏️ ```javascript import { authenticateToken } from '../middlewares/authMiddleware.js'; // Publikus router.post('/register', ...); router.post('/login', ...); router.post('/refresh', ...); // Védett - add hozzá az authenticateToken middleware-t! router.post('/logout', authenticateToken, ...); router.get('/me', authenticateToken, ...); ``` #### `src/api/routes/blogRoutes.js` ✏️ ```javascript import { authenticateToken, checkOwnership } from '../middlewares/authMiddleware.js'; // Publikus router.get('/', ...); router.get('/:id', ...); // Védett - add hozzá a middleware-eket! router.post('/', authenticateToken, ...); router.put('/:id', authenticateToken, checkOwnership(...), ...); router.delete('/:id', authenticateToken, checkOwnership(...), ...); ``` --- ## 📋 Ellenőrző Lista Implementációd kész, ha az alábbiak működnek: ```bash # 1. Regisztráció curl -X POST http://localhost:3000/api/auth/register \ -H "Content-Type: application/json" \ -d '{ "email": "test@test.com", "username": "testuser", "password": "Test1234" }' # → 201 Created, user adatok, cookie beállítva # 2. Bejelentkezés curl -X POST http://localhost:3000/api/auth/login \ -H "Content-Type: application/json" \ -d '{ "email": "test@test.com", "password": "Test1234" }' # → 200 OK, user adatok, cookie beállítva # 3. Current user curl -X GET http://localhost:3000/api/auth/me \ -H "Authorization: Bearer " # → 200 OK, user adatok # 4. Blog létrehozás (védett) curl -X POST http://localhost:3000/api/blogs \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"title": "Test", "content": "Content"}' # → 201 Created # 5. Másik user blogja - módosítás TILOS curl -X PUT http://localhost:3000/api/blogs/ \ -H "Authorization: Bearer " \ -d '{"title": "Hacked"}' # → 403 Forbidden # 6. Saját blog - módosítás OK curl -X PUT http://localhost:3000/api/blogs/ \ -H "Authorization: Bearer " \ -d '{"title": "Updated"}' # → 200 OK # 7. Kijelentkezés curl -X POST http://localhost:3000/api/auth/logout \ -H "Authorization: Bearer " # → 200 OK, cookie törölve ``` --- ## 🔑 Kulcs Fontosságú Részek ### JWT Token Struktúra ```javascript { userId: "uuid...", email: "user@example.com", role: "USER", iat: 1234567890, // issued at exp: 1234999999 // expires } ``` ### Cookie Options ```javascript { httpOnly: true, // JavaScript nem fér hozzá secure: true, // Csak HTTPS (production) sameSite: 'strict', // CSRF védelem maxAge: 7 * 24 * 60 * 60 * 1000 // millisec } ``` ### Környezeti Változók ```env JWT_SECRET=minimum-32-karakter-hosszu-random-string JWT_REFRESH_SECRET=egy-masik-32-karakter-hosszu-string JWT_EXPIRES_IN=7d JWT_REFRESH_EXPIRES_IN=30d COOKIE_SECRET=meg-egy-secret ``` --- ## ⚡ Gyors Start ```bash # 1. Telepítés npm install # 2. Env fájl cp .env.example .env # Szerkeszd a .env fájlt! # 3. Docker indítás npm run docker:up # 4. Migráció npm run prisma:migrate npm run prisma:generate # 5. Szerver indítás npm run dev # 6. Implementáld az auth részeket # - AuthController: register, login, logout, refresh, getCurrentUser # - authMiddleware: authenticateToken, requireRole, checkOwnership # - Routes: add hozzá a middleware-eket # 7. Tesztelés # Használd a fenti curl parancsokat ``` --- ## 🚨 Gyakori Hibák ❌ **Jelszó plain text-ben van tárolva** ✅ Használd: `bcrypt.hash(password, 10)` ❌ **Token nincs validálva** ✅ Használd: `jwt.verify(token, secret)` ❌ **Cookie nem httpOnly** ✅ Állítsd be: `httpOnly: true` a cookie options-ben ❌ **Rossz paraméter sorrend bcrypt.compare()-nál** ✅ Helyes: `bcrypt.compare(plainPassword, hashedPassword)` ❌ **req.user nincs beállítva** ✅ Az authenticateToken middleware-nek kell beállítania! --- ## 🎯 Mit Tanulsz - ✅ JWT-based authentication - ✅ Cookie management (httpOnly, secure, sameSite) - ✅ Password hashing (bcrypt) - ✅ Middleware pattern - ✅ Role-based access control (RBAC) - ✅ Resource ownership validation - ✅ Clean architecture - ✅ CQRS pattern - ✅ Repository pattern - ✅ Dependency injection --- **Kezdj neki és sok sikert! 💪**