harmadik gyakorlat

This commit is contained in:
magdo
2026-02-25 20:16:03 +01:00
parent a837f5ecba
commit ffca701b84
34 changed files with 3397 additions and 0 deletions
+300
View File
@@ -0,0 +1,300 @@
# 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 <token>"
# → 200 OK, user adatok
# 4. Blog létrehozás (védett)
curl -X POST http://localhost:3000/api/blogs \
-H "Authorization: Bearer <token>" \
-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/<mas_user_blog_id> \
-H "Authorization: Bearer <token>" \
-d '{"title": "Hacked"}'
# → 403 Forbidden
# 6. Saját blog - módosítás OK
curl -X PUT http://localhost:3000/api/blogs/<sajat_blog_id> \
-H "Authorization: Bearer <token>" \
-d '{"title": "Updated"}'
# → 200 OK
# 7. Kijelentkezés
curl -X POST http://localhost:3000/api/auth/logout \
-H "Authorization: Bearer <token>"
# → 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! 💪**