Kotchasan Framework Documentation

Kotchasan Framework Documentation

การจัดการการยืนยันตัวตนและความปลอดภัย

TH 05 Feb 2026 06:50

การจัดการการยืนยันตัวตนและความปลอดภัย

Kotchasan Framework มีระบบจัดการการยืนยันตัวตนและความปลอดภัยที่ครอบคลุม รองรับหลายรูปแบบการยืนยันตัวตน รวมถึงการป้องกันการโจมตีทางความปลอดภัยต่างๆ

สารบัญ

  1. Login Class - การจัดการการเข้าสู่ระบบ
  2. Password Class - การจัดการรหัสผ่านและการเข้ารหัส
  3. Session Class - การจัดการ Session
  4. JWT Middleware - การยืนยันตัวตนด้วย JWT
  5. AuthFactory - Factory สำหรับการยืนยันตัวตน
  6. CSRF Protection - การป้องกัน CSRF
  7. ตัวอย่างการใช้งานในระบบจริง

Login Class - การจัดการการเข้าสู่ระบบ

การใช้งาน Login Class

use Kotchasan\Login;
use Kotchasan\Http\Request;

// สร้าง Login instance
$request = new Request();
$login = Login::create($request);

// ตรวจสอบสถานะการเข้าสู่ระบบ
$user = Login::isMember();
if ($user) {
    echo "ผู้ใช้: " . $user['username'];
} else {
    echo "ยังไม่ได้เข้าสู่ระบบ";
}

// ตรวจสอบสิทธิ์ Admin
$admin = Login::isAdmin();
if ($admin) {
    echo "มีสิทธิ์ Admin";
}

การตั้งค่าการเข้าสู่ระบบ

class CustomLogin extends Login
{
    /**
     * ตรวจสอบข้อมูลการเข้าสู่ระบบกับฐานข้อมูล
     */
    public function checkLogin($loginParams)
    {
        // ตรวจสอบ username
        $user = $this->db()
            ->select()
            ->from('users')
            ->where(['username', $loginParams['username']])
            ->first();

        if (!$user) {
            self::$login_input = 'username';
            return 'ไม่พบผู้ใช้งานนี้';
        }

        // ตรวจสอบรหัสผ่าน
        if (!password_verify($loginParams['password'], $user->password)) {
            self::$login_input = 'password';
            return 'รหัสผ่านไม่ถูกต้อง';
        }

        // ตรวจสอบสถานะผู้ใช้
        if ($user->status == 0) {
            return 'บัญชีของคุณถูกระงับ';
        }

        // อัปเดตข้อมูลการเข้าสู่ระบบล่าสุด
        $this->db()->update('users')
            ->set([
                'last_login' => date('Y-m-d H:i:s'),
                'login_ip' => $_SERVER['REMOTE_ADDR']
            ])
            ->where(['id', $user->id])
            ->execute();

        // คืนข้อมูลผู้ใช้
        return [
            'id' => $user->id,
            'username' => $user->username,
            'email' => $user->email,
            'name' => $user->name,
            'status' => $user->status,
            'permissions' => explode(',', $user->permissions)
        ];
    }

    /**
     * การออกจากระบบ
     */
    public function logout(Request $request)
    {
        // ล้างข้อมูล session
        $key = static::sessionKey();
        unset($_SESSION[$key]);

        // ล้าง remember me cookie ถ้ามี
        if (isset($_COOKIE['remember_me'])) {
            setcookie('remember_me', '', time() - 3600, '/');
        }

        // บันทึกการออกจากระบบ
        $this->logActivity('logout');

        self::$login_message = 'ออกจากระบบเรียบร้อยแล้ว';
        self::$login_params = [];
    }

    /**
     * การรีเซ็ตรหัสผ่าน
     */
    public function forgot(Request $request)
    {
        $email = $request->post('email')->email();

        if (empty($email)) {
            self::$login_message = 'กรุณากรอกอีเมล';
            return;
        }

        // ตรวจสอบอีเมลในระบบ
        $user = $this->db()
            ->select()
            ->from('users')
            ->where(['email', $email])
            ->first();

        if (!$user) {
            self::$login_message = 'ไม่พบอีเมลนี้ในระบบ';
            return;
        }

        // สร้าง reset token
        $resetToken = Password::uniqid(32);
        $expiry = date('Y-m-d H:i:s', strtotime('+1 hour'));

        // บันทึก reset token
        $this->db()->update('users')
            ->set([
                'reset_token' => $resetToken,
                'reset_expires' => $expiry
            ])
            ->where(['id', $user->id])
            ->execute();

        // ส่งอีเมลรีเซ็ตรหัสผ่าน
        $this->sendResetEmail($user, $resetToken);

        self::$login_message = 'ส่งลิงก์รีเซ็ตรหัสผ่านไปยังอีเมลของคุณแล้ว';
    }
}

การตรวจสอบสิทธิ์

// ตรวจสอบสิทธิ์แบบเฉพาะเจาะจง
$user = Login::isMember();
$hasPermission = Login::checkStatus($user, [1, 2, 3]); // สถานะที่อนุญาต

// การใช้งานใน Controller
class AdminController
{
    public function index()
    {
        // ตรวจสอบสิทธิ์ Admin
        $admin = Login::isAdmin();
        if (!$admin) {
            // Redirect to login page
            header('Location: /login');
            exit;
        }

        // แสดงหน้า Admin
        return $this->view->render('admin/dashboard', [
            'user' => $admin
        ]);
    }

    public function users()
    {
        // ตรวจสอบสิทธิ์เฉพาะ
        $user = Login::isMember();
        if (!Login::checkStatus($user, [1, 2])) { // Admin และ Manager
            throw new \Exception('Access denied');
        }

        // แสดงรายการผู้ใช้
        return $this->userService->getUsers();
    }
}

Password Class - การจัดการรหัสผ่านและการเข้ารหัส

การเข้ารหัสและถอดรหัสข้อมูล

use Kotchasan\Password;

// การเข้ารหัสข้อมูล
$data = "ข้อมูลลับ";
$secretKey = "my-secret-key";
$encrypted = Password::encode($data, $secretKey);

// การถอดรหัสข้อมูล
try {
    $decrypted = Password::decode($encrypted, $secretKey);
    echo $decrypted; // "ข้อมูลลับ"
} catch (Exception $e) {
    echo "การถอดรหัสล้มเหลว: " . $e->getMessage();
}

// การเข้ารหัสรหัสผ่าน
$password = "user-password123";
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);

// การตรวจสอบรหัสผ่าน
if (password_verify($password, $hashedPassword)) {
    echo "รหัสผ่านถูกต้อง";
}

การสร้าง Token และ API Signature

// การสร้าง unique ID
$shortId = Password::uniqid(8);     // 8 ตัวอักษร
$longId = Password::uniqid(32);     // 32 ตัวอักษร
$defaultId = Password::uniqid();    // 13 ตัวอักษร (default)

// การสร้าง API signature
$apiParams = [
    'user_id' => 123,
    'action' => 'get_data',
    'timestamp' => time()
];
$apiSecret = 'api-secret-key';
$signature = Password::generateSign($apiParams, $apiSecret);

// การตรวจสอบ API signature
function validateApiSignature($params, $receivedSignature, $secret)
{
    $expectedSignature = Password::generateSign($params, $secret);
    return hash_equals($expectedSignature, $receivedSignature);
}

การใช้งานในระบบจริง

class UserService
{
    /**
     * การสร้างบัญชีผู้ใช้ใหม่
     */
    public function createUser($userData)
    {
        // เข้ารหัสรหัสผ่าน
        $userData['password'] = password_hash($userData['password'], PASSWORD_DEFAULT);

        // สร้าง activation token
        $userData['activation_token'] = Password::uniqid(32);
        $userData['created_at'] = date('Y-m-d H:i:s');

        // บันทึกผู้ใช้ใหม่
        $userId = $this->db()->insert('users')->values($userData)->execute();

        // ส่งอีเมลยืนยัน
        $this->sendActivationEmail($userData);

        return $userId;
    }

    /**
     * การเปลี่ยนรหัสผ่าน
     */
    public function changePassword($userId, $oldPassword, $newPassword)
    {
        // ดึงข้อมูลผู้ใช้
        $user = $this->db()->select()->from('users')->where(['id', $userId])->first();

        // ตรวจสอบรหัสผ่านเดิม
        if (!password_verify($oldPassword, $user->password)) {
            throw new \Exception('รหัสผ่านเดิมไม่ถูกต้อง');
        }

        // ตรวจสอบความแข็งแรงของรหัสผ่านใหม่
        if (strlen($newPassword) < 8) {
            throw new \Exception('รหัสผ่านต้องมีอย่างน้อย 8 ตัวอักษร');
        }

        // เข้ารหัสรหัสผ่านใหม่
        $hashedPassword = password_hash($newPassword, PASSWORD_DEFAULT);

        // อัปเดตรหัสผ่าน
        $this->db()->update('users')
            ->set(['password' => $hashedPassword, 'password_changed_at' => date('Y-m-d H:i:s')])
            ->where(['id', $userId])
            ->execute();

        return true;
    }
}

Session Class - การจัดการ Session

การตั้งค่า Session ในฐานข้อมูล

use Kotchasan\Session;

// การใช้งาน Session ในฐานข้อมูล
$session = new Session();

// สร้างตารางสำหรับ Session
$session->createTable();

// การตั้งค่า Session Handler
session_set_save_handler(
    [$session, '_open'],
    [$session, '_close'],
    [$session, '_read'],
    [$session, '_write'],
    [$session, '_destroy'],
    [$session, '_gc']
);

// เริ่ม Session
session_start();

การใช้งาน Session

// การเก็บข้อมูลใน Session
$session = new Session();
$session->setSession('user_id', 123);
$session->setSession('username', 'john_doe');
$session->setSession('cart', ['item1', 'item2']);

// การดึงข้อมูลจาก Session
$userId = $session->session('user_id');
$username = $session->session('username', 'anonymous');
$cart = $session->session('cart', []);

// การใช้งานแบบปกติ
$_SESSION['custom_data'] = 'some value';
$customData = $_SESSION['custom_data'] ?? 'default';

การตั้งค่าความปลอดภัยของ Session

// การตั้งค่า Session อย่างปลอดภัย
ini_set('session.use_only_cookies', 1);
ini_set('session.use_strict_mode', 1);
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', 1); // เฉพาะ HTTPS
ini_set('session.cookie_samesite', 'Lax');

// การตั้งค่า Session Cookie
session_set_cookie_params([
    'lifetime' => 0,
    'path' => '/',
    'domain' => '',
    'secure' => true,    // เฉพาะ HTTPS
    'httponly' => true,  // ป้องกัน XSS
    'samesite' => 'Lax'  // ป้องกัน CSRF
]);

// การ regenerate Session ID
function regenerateSessionId()
{
    if (session_status() === PHP_SESSION_ACTIVE) {
        session_regenerate_id(true);
    }
}

// การตรวจสอบ Session ที่หมดอายุ
$maxLifetime = 360; // 0)
{
    if (isset($_SESSION['last_activity'])) {
        if (time() - $_SESSION['last_activity'] > $maxLifetime) {
            session_destroy();
            return false;
        }
    }
    $_SESSION['last_activity'] = time();
    return true;
}

JWT Middleware - การยืนยันตัวตนด้วย JWT

การใช้งาน JWT Middleware

use Kotchasan\Http\Middleware\JwtMiddleware;

// การสร้าง JWT Middleware
$secretKey = 'your-secret-key-here';
$jwtMiddleware = new JwtMiddleware($secretKey);

// การตั้งค่าตัวเลือก
$options = [
    'algorithm' => 'HS256',
    'tokenParam' => 'token',    // รับ token จาก query parameter
    'required' => true          // บังคับต้องมี token
];
$jwtMiddleware = new JwtMiddleware($secretKey, $options);

// การใช้งานใน Controller
class ApiController
{
    public function getData(Request $request)
    {
        $jwt = new JwtMiddleware('secret-key');
        $response = $jwt->handle($request);

        if ($response instanceof Response) {
            // Token ไม่ถูกต้อง
            return $response;
        }

        // ดึงข้อมูลผู้ใช้จาก token
        $userId = $request->getAttribute('authenticated_user');
        $payload = $request->getAttribute('jwt_payload');

        return [
            'user_id' => $userId,
            'data' => $this->getUserData($userId)
        ];
    }
}

การสร้างและการตรวจสอบ JWT Token

// การสร้าง JWT Token
$jwt = new JwtMiddleware('secret-key');

// การสร้าง token ด้วย user ID
$token = $jwt->generateToken(123, 3600); // user ID = 123, หมดอายุ 1 ชั่วโมง

// การสร้าง token ด้วย payload กำหนดเอง
$payload = [
    'user_id' => 123,
    'username' => 'john_doe',
    'role' => 'admin',
    'permissions' => ['read', 'write', 'delete']
];
$token = $jwt->generateToken($payload, 7200); // หมดอายุ 2 ชั่วโมง

// การถอดรหัส JWT Token
try {
    $decoded = $jwt->decodeToken($token);
    echo "User ID: " . $decoded['sub'];
    echo "Expires: " . date('Y-m-d H:i:s', $decoded['exp']);
} catch (Exception $e) {
    echo "Token ไม่ถูกต้อง: " . $e->getMessage();
}

การใช้ JWT ในระบบ API

class AuthApiController
{
    /**
     * เข้าสู่ระบบและสร้าง JWT token
     */
    public function login(Request $request)
    {
        $username = $request->post('username')->username();
        $password = $request->post('password')->password();

        // ตรวจสอบข้อมูลเข้าสู่ระบบ
        $user = $this->validateLogin($username, $password);
        if (!$user) {
            return Response::makeUnauthorized(['error' => 'Invalid credentials']);
        }

        // สร้าง JWT token
        $jwt = new JwtMiddleware(self::$cfg->jwt_secret);
        $payload = [
            'sub' => $user['id'],
            'username' => $user['username'],
            'role' => $user['role'],
            'iat' => time(),
            'exp' => time() + 3600 // หมดอายุ 1 ชั่วโมง
        ];

        $accessToken = $jwt->generateToken($payload);
        $refreshToken = Password::uniqid(40);

        // บันทึก refresh token
        $this->saveRefreshToken($user['id'], $refreshToken);

        return Response::makeOk([
            'access_token' => $accessToken,
            'refresh_token' => $refreshToken,
            'token_type' => 'Bearer',
            'expires_in' => 3600
        ]);
    }

    /**
     * รีเฟรช JWT token
     */
    public function refreshToken(Request $request)
    {
        $refreshToken = $request->post('refresh_token')->toString();

        // ตรวจสอบ refresh token
        $user = $this->validateRefreshToken($refreshToken);
        if (!$user) {
            return Response::makeUnauthorized(['error' => 'Invalid refresh token']);
        }

        // สร้าง access token ใหม่
        $jwt = new JwtMiddleware(self::$cfg->jwt_secret);
        $newAccessToken = $jwt->generateToken([
            'sub' => $user['id'],
            'username' => $user['username'],
            'role' => $user['role']
        ], 3600);

        // สร้าง refresh token ใหม่
        $newRefreshToken = Password::uniqid(40);
        $this->updateRefreshToken($user['id'], $newRefreshToken);

        return Response::makeOk([
            'access_token' => $newAccessToken,
            'refresh_token' => $newRefreshToken,
            'token_type' => 'Bearer',
            'expires_in' => 3600
        ]);
    }
}

AuthFactory - Factory สำหรับการยืนยันตัวตน

การใช้งาน AuthFactory

use Kotchasan\Http\Auth\AuthFactory;

// การจัดการรหัสผ่าน
$password = 'user-password123';
$hashedPassword = AuthFactory::hashPassword($password);
$isValid = AuthFactory::verifyPassword($password, $hashedPassword);

// การสร้าง random token
$token = AuthFactory::generateToken(32); // 32 ตัวอักษร
$shortToken = AuthFactory::generateToken(16); // 16 ตัวอักษร

// การสร้างและตรวจสอบ JWT token
$payload = ['user_id' => 123, 'role' => 'admin'];
$secretKey = 'jwt-secret-key';
$jwtToken = AuthFactory::createJwtToken($payload, $secretKey);
$decodedPayload = AuthFactory::validateJwtToken($jwtToken, $secretKey);

การสร้าง Authentication Middleware

// Basic Authentication
$basicAuth = AuthFactory::createBasicAuth(function($username, $password) {
    // ตรวจสอบ username และ password
    return $this->validateUser($username, $password);
}, 'Admin Area');

// JWT Authentication
$jwtAuth = AuthFactory::createJwtAuth('secret-key', 'HS256');

// Bearer Token Authentication
$bearerAuth = AuthFactory::createBearerTokenAuth(function($token) {
    // ตรวจสอบ bearer token
    return $this->validateBearerToken($token);
});

// Digest Authentication
$digestAuth = AuthFactory::createDigestAuth(function($username) {
    // คืนค่า password hash สำหรับ username
    return $this->getUserPasswordHash($username);
}, 'Secure Area');

// Authorization (Role-based)
$authorization = AuthFactory::createAuthorization(['admin', 'manager']);

การเปรียบเทียบ Hash อย่างปลอดภัย

// การเปรียบเทียบ hash ที่ป้องกัน timing attack
$hash1 = hash('sha256', 'data1');
$hash2 = hash('sha256', 'data2');

// วิธีที่ไม่ปลอดภัย
if ($hash1 === $hash2) {
    // อาจเสี่ยงต่อ timing attack
}

// วิธีที่ปลอดภัย
if (AuthFactory::compareHashes($hash1, $hash2)) {
    // ป้องกัน timing attack
}

CSRF Protection - การป้องกัน CSRF

การใช้งาน CSRF Protection

// การสร้าง CSRF token
$csrfToken = AuthFactory::generateCsrfToken();
$customToken = AuthFactory::generateCsrfToken('custom_csrf_key');

// การตรวจสอบ CSRF token
$isValid = AuthFactory::validateCsrfToken($_POST['csrf_token']);
$customIsValid = AuthFactory::validateCsrfToken($_POST['custom_token'], 'custom_csrf_key');

// การใช้งานใน Form
echo '<input type="hidden" name="csrf_token" value="' . htmlspecialchars($csrfToken) . '">';

การป้องกัน CSRF ใน Controller

class FormController
{
    public function showForm()
    {
        // สร้าง CSRF token สำหรับ form
        $csrfToken = AuthFactory::generateCsrfToken();

        return $this->view->render('form', [
            'csrf_token' => $csrfToken
        ]);
    }

    public function processForm(Request $request)
    {
        // ตรวจสอบ CSRF token
        $token = $request->post('csrf_token')->toString();
        if (!AuthFactory::validateCsrfToken($token)) {
            return Response::makeForbidden(['error' => 'Invalid CSRF token']);
        }

        // ประมวลผล form
        $data = [
            'name' => $request->post('name')->toString(),
            'email' => $request->post('email')->email()
        ];

        $result = $this->processData($data);

        return Response::makeOk(['message' => 'Form processed successfully']);
    }
}

CSRF Protection สำหรับ API

class ApiCsrfController
{
    /**
     * รับ CSRF token สำหรับ SPA/AJAX
     */
    public function getCsrfToken(Request $request)
    {
        $token = AuthFactory::generateCsrfToken('api_csrf_token');

        return Response::makeOk([
            'csrf_token' => $token,
            'expires_in' => 3600
        ]);
    }

    /*
     * ตรวจสอบ CSRF token ในการเรียก API
     */
    public function validateApiCsrf(Request $request)
    {
        $token = $request->getHeaderLine('X-CSRF-Token')
               ?: $request->post('csrf_token')->toString();

        if (!AuthFactory::validateCsrfToken($token, 'api_csrf_token')) {
            return Response::makeForbidden([
                'error' => 'CSRF token validation failed',
                'code' => 'INVALID_CSRF_TOKEN'
            ]);
        }

        return null; // ผ่านการตรวจสอบ
    }
}

ตัวอย่างการใช้งานในระบบจริง

ระบบการเข้าสู่ระบบแบบครอบคลุม

use Kotchasan\Database;

class AuthenticationSystem
{
    private $db;
    private $jwtSecret;

    public function __construct()
    {
        $this->db = Kotchasan\Database::create();
        $this->jwtSecret = Config::get('jwt_secret');
    }

    /**
     * ระบบเข้าสู่ระบบแบบครบครัน
     */
    public function login(Request $request)
    {
        try {
            // ตรวจสอบ CSRF token
            $csrfToken = $request->post('csrf_token')->toString();
            if (!AuthFactory::validateCsrfToken($csrfToken)) {
                return $this->errorResponse('Invalid CSRF token', 403);
            }

            // ตรวจสอบ rate limiting
            $clientIp = $request->server('REMOTE_ADDR');
            if (!$this->checkRateLimit($clientIp, 'login', 5, 300)) {
                return $this->errorResponse('Too many login attempts', 429);
            }

            $username = $request->post('username')->username();
            $password = $request->post('password')->password();
            $rememberMe = $request->post('remember_me')->toBool();

            // ตรวจสอบข้อมูลเข้าสู่ระบบ
            $user = $this->validateCredentials($username, $password);
            if (!$user) {
                $this->logFailedLogin($username, $clientIp);
                return $this->errorResponse('Invalid credentials', 401);
            }

            // ตรวจสอบสถานะบัญชี
            if ($user['status'] !== 'active') {
                return $this->errorResponse('Account is not active', 403);
            }

            // สร้าง session
            session_regenerate_id(true);
            $_SESSION['user'] = [
                'id' => $user['id'],
                'username' => $user['username'],
                'role' => $user['role'],
                'login_time' => time()
            ];

            // สร้าง JWT token
            $jwtToken = null;
            if ($request->post('api_access')->toBool()) {
                $jwt = new JwtMiddleware($this->jwtSecret);
                $jwtToken = $jwt->generateToken([
                    'sub' => $user['id'],
                    'username' => $user['username'],
                    'role' => $user['role']
                ], 3600);
            }

            // จัดการ Remember Me
            if ($rememberMe) {
                $this->setRememberMeCookie($user['id']);
            }

            // บันทึกการเข้าสู่ระบบ
            $this->logSuccessfulLogin($user['id'], $clientIp);

            return $this->successResponse([
                'message' => 'Login successful',
                'user' => [
                    'id' => $user['id'],
                    'username' => $user['username'],
                    'role' => $user['role']
                ],
                'jwt_token' => $jwtToken,
                'csrf_token' => AuthFactory::generateCsrfToken()
            ]);

        } catch (Exception $e) {
            return $this->errorResponse('Login failed: ' . $e->getMessage(), 500);
        }
    }

    /**
     * ตรวจสอบข้อมูลประจำตัว
     */
    private function validateCredentials($username, $password)
    {
        // ค้นหาผู้ใช้
        $user = $this->db->select()
            ->from('users')
            ->where(['username', $username])
            ->orWhere(['email', $username])
            ->first();

        if (!$user) {
            return false;
        }

        // ตรวจสอบรหัสผ่าน
        if (!AuthFactory::verifyPassword($password, $user->password)) {
            return false;
        }

        return $user->toArray();
    }

    /**
     * จัดการ Remember Me Cookie
     */
    private function setRememberMeCookie($userId)
    {
        $token = AuthFactory::generateToken(32);
        $expires = time() + (30  24  60  60); // 30 วัน

        // บันทึก remember token ในฐานข้อมูล
        $this->db->insert('remember_tokens')
            ->values([
                'user_id' => $userId,
                'token' => hash('sha256', $token),
                'expires_at' => date('Y-m-d H:i:s', $expires),
                'created_at' => date('Y-m-d H:i:s')
            ])
            ->execute();

        // ตั้งค่า cookie
        setcookie('remember_me', $token, $expires, '/', '', true, true);
    }

    /**
     * ตรวจสอบ Rate Limiting
     */
    private function checkRateLimit($identifier, $action, $limit, $window)
    {
        $key = "rate_limit:{$action}:{$identifier}";
        $attempts = $_SESSION[$key] ?? [];

        // ลบความพยายามที่เก่าเกินไป
        $cutoff = time() - $window;
        $attempts = array_filter($attempts, function($time) use ($cutoff) {
            return $time > $cutoff;
        });

        // ตรวจสอบขีดจำกัด
        if (count($attempts) >= $limit) {
            return false;
        }

        // บันทึกความพยายามใหม่
        $attempts[] = time();
        $_SESSION[$key] = $attempts;

        return true;
    }

    /**
     * บันทึกการเข้าสู่ระบบที่สำเร็จ
     */
    private function logSuccessfulLogin($userId, $ip)
    {
        $this->db->insert('login_logs')
            ->values([
                'user_id' => $userId,
                'ip_address' => $ip,
                'status' => 'success',
                'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
                'created_at' => date('Y-m-d H:i:s')
            ])
            ->execute();
    }

    /**
     * บันทึกการเข้าสู่ระบบที่ล้มเหลว
     */
    private function logFailedLogin($username, $ip)
    {
        $this->db->insert('login_logs')
            ->values([
                'username' => $username,
                'ip_address' => $ip,
                'status' => 'failed',
                'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
                'created_at' => date('Y-m-d H:i:s')
            ])
            ->execute();
    }
}

ระบบป้องกันความปลอดภัยแบบหลายชั้น

class SecuritySystem
{
    /**
     * ระบบป้องกันแบบครอบคลุม
     */
    public function securityMiddleware(Request $request, callable $next)
    {
        // 1. ตรวจสอบ IP whitelist/blacklist
        if (!$this->validateIpAccess($request->server('REMOTE_ADDR'))) {
            return Response::makeForbidden(['error' => 'IP not allowed']);
        }

        // 2. ตรวจสอบ User Agent
        if (!$this->validateUserAgent($request->server('HTTP_USER_AGENT'))) {
            return Response::makeForbidden(['error' => 'Invalid user agent']);
        }

        // 3. ตรวจสอบ Referer สำหรับ state-changing requests
        if (in_array($request->getMethod(), ['POST', 'PUT', 'DELETE', 'PATCH'])) {
            if (!$this->validateReferer($request)) {
                return Response::makeForbidden(['error' => 'Invalid referer']);
            }
        }

        // 4. ตรวจสอบ CSRF token สำหรับ state-changing requests
        if ($request->isMethod('POST')) {
            $csrfToken = $request->getHeaderLine('X-CSRF-Token')
                      ?: $request->post('csrf_token')->toString();
            if (!AuthFactory::validateCsrfToken($csrfToken)) {
                return Response::makeForbidden(['error' => 'CSRF validation failed']);
            }
        }

        // 5. ตรวจสอบ JWT token สำหรับ API requests
        if (strpos($request->getHeaderLine('Accept'), 'application/json') !== false) {
            $jwt = new JwtMiddleware(Config::get('jwt_secret'));
            $response = $jwt->handle($request);
            if ($response instanceof Response) {
                return $response;
            }
        }

        // 6. ตรวจสอบ permissions
        $user = $request->getAttribute('authenticated_user');
        if (!$this->hasPermission($user, $request)) {
            return Response::makeForbidden(['error' => 'Insufficient permissions']);
        }

        // 7. Rate limiting
        if (!$this->checkGlobalRateLimit($request)) {
            return Response::make(['error' => 'Rate limit exceeded'], 429);
        }

        // ผ่านการตรวจสอบทั้งหมด
        return $next($request);
    }

    /**
     * การตรวจสอบสิทธิ์การเข้าถึง
     */
    private function hasPermission($userId, Request $request)
    {
        if (!$userId) {
            return false; // ต้องเข้าสู่ระบบ
        }

        $route = $request->getAttribute('route');
        $action = $request->getMethod() . ' ' . $route;

        // ตรวจสอบ permissions จากฐานข้อมูล
        $hasPermission = $this->db->select('COUNT()')
            ->from('user_permissions')
            ->where(['user_id', $userId])
            ->where(['permission', $action])
            ->where(['status', 'active'])
            ->value();

        return $hasPermission > 0;
    }

    /**
     * การตรวจสอบ IP access
     */
    private function validateIpAccess($clientIp)
    {
        // ตรวจสอบ IP blacklist
        $blacklisted = $this->db->select('COUNT()')
            ->from('ip_blacklist')
            ->where(['ip_address', $clientIp])
            ->where(['status', 'active'])
            ->value();

        if ($blacklisted > 0) {
            return false;
        }

        // ตรวจสอบ IP whitelist (ถ้ามี)
        $whitelistCount = $this->db->select('COUNT()')
            ->from('ip_whitelist')
            ->where(['status', 'active'])
            ->value();

        if ($whitelistCount > 0) {
            $whitelisted = $this->db->select('COUNT()')
                ->from('ip_whitelist')
                ->where(['ip_address', $clientIp])
                ->where(['status', 'active'])
                ->value();

            return $whitelisted > 0;
        }

        return true;
    }

    /**
     * การป้องกัน Brute Force Attack
     */
    public function bruteForcePrevention($identifier, $action, $maxAttempts = 5, $blockTime = 300)
    {
        $key = "brute_force:{$action}:{$identifier}";
        $data = $_SESSION[$key] ?? ['attempts' => 0, 'last_attempt' => 0];

        // ตรวจสอบว่าถูกบล็อกอยู่หรือไม่
        if ($data['attempts'] >= $maxAttempts) {
            $timeSinceBlock = time() - $data['last_attempt'];
            if ($timeSinceBlock < $blockTime) {
                $remainingTime = $blockTime - $timeSinceBlock;
                throw new \Exception("Account blocked. Try again in {$remainingTime} seconds.");
            } else {
                // หมดเวลาบล็อก รีเซ็ตการนับ
                $data = ['attempts' => 0, 'last_attempt' => 0];
            }
        }

        // เพิ่มจำนวนครั้งที่พยายาม
        $data['attempts']++;
        $data['last_attempt'] = time();
        $_SESSION[$key] = $data;

        return $data['attempts'];
    }
}

Kotchasan Framework มีระบบการจัดการการยืนยันตัวตนและความปลอดภัยที่ครอบคลุม รองรับการพัฒนาแอปพลิเคชันที่ปลอดภัยและมีประสิทธิภาพสูง พร้อมด้วยการป้องกันการโจมตีทางความปลอดภัยในรูปแบบต่างๆ