본문으로 건너뛰기

เนื้อหาภาษาไทย / 태국어 콘텐츠

시스템 가이드 검수 완료된 콘텐츠

การ Implement Authentication ด้วย API Key

บทนี้อธิบายวิธีการ Implement ระบบ Authentication ด้วย API Key โดยรับ API Key จาก HTTP Header, ตรวจสอบความถูกต้องของ API Key กับข้อมูลในฐานข้อมูล, และควบคุมการเข...

การ Implement Authentication ด้วย API Key

จากบทที่แล้ว เราได้เรียนรู้วิธีการสร้าง API Key และเก็บรักษาไว้ในฐานข้อมูล ในบทนี้ เราจะมาลงมือ Implement ระบบ Authentication โดยใช้ API Key ที่เราสร้างขึ้นมา เพื่อควบคุมการเข้าถึง API ของเรา

เป้าหมายของบทเรียนนี้

  • เข้าใจหลักการทำงานของการ Authentication ด้วย API Key
  • สามารถรับ API Key จาก HTTP Header
  • สามารถตรวจสอบความถูกต้องของ API Key กับข้อมูลในฐานข้อมูล
  • สามารถควบคุมการเข้าถึง API โดยอิงจาก API Key

ภาพรวมการทำงาน

กระบวนการ Authentication ด้วย API Key จะเป็นดังนี้:

  1. Client ส่ง Request มายัง API พร้อมกับ API Key ใน HTTP Header
  2. API ตรวจสอบว่ามี API Key อยู่ใน Header หรือไม่
  3. ถ้ามี API Key, API จะตรวจสอบว่า API Key นั้นถูกต้องหรือไม่ โดยเทียบกับข้อมูลในฐานข้อมูล
  4. ถ้า API Key ถูกต้อง, API จะอนุญาตให้เข้าถึง Endpoint ที่ Request มา
  5. ถ้า API Key ไม่ถูกต้อง หรือไม่มี API Key, API จะปฏิเสธการเข้าถึง และส่ง Error Response กลับไป

ขั้นตอนการ Implement

1. การรับ API Key จาก Header

เราจะรับ API Key จาก HTTP Header ชื่อ X-API-Key (สามารถตั้งชื่ออื่นได้ตามต้องการ)

ตัวอย่างโค้ด PHP:

<?php

// ฟังก์ชันสำหรับดึงค่า Header จาก Request
function getAuthorizationHeader(){
    $headers = null;
    if (isset($_SERVER['Authorization'])) {
        $headers = trim($_SERVER["Authorization"]);
    }
    else if (isset($_SERVER['HTTP_AUTHORIZATION'])) { //Nginx or fast CGI
        $headers = trim($_SERVER["HTTP_AUTHORIZATION"]);
    } elseif (function_exists('apache_request_headers')) {
        $requestHeaders = apache_request_headers();
        // Server-side fix for HTTP authentication header passed as `Authorization`
        if (isset($requestHeaders['Authorization'])) {
            $headers = trim($requestHeaders['Authorization']);
        }
    }
    return $headers;
}

// ดึงค่า Authorization Header
$authHeader = getAuthorizationHeader();

// แยก Bearer ออกจาก Token (ถ้ามี)
$apiKey = null;
if (!empty($authHeader)) {
    if (preg_match('/Bearer\s(\S+)/', $authHeader, $matches)) {
        $apiKey = $matches[1];
    }
}

// ถ้าไม่มี Authorization Header ให้ลองดึงจาก X-API-Key
if (empty($apiKey) && isset($_SERVER['HTTP_X_API_KEY'])) {
    $apiKey = $_SERVER['HTTP_X_API_KEY'];
}

// ตรวจสอบว่ามี API Key หรือไม่
if ($apiKey === null) {
    // ไม่พบ API Key
    http_response_code(401); // Unauthorized
    echo json_encode(['message' => 'API Key not provided']);
    exit;
}

// ตอนนี้เรามี API Key อยู่ในตัวแปร $apiKey แล้ว
// ขั้นตอนต่อไปคือการตรวจสอบความถูกต้อง

คำอธิบายโค้ด:

  • ฟังก์ชัน getAuthorizationHeader() ใช้สำหรับดึงค่า Authorization Header จาก HTTP Request ไม่ว่าจะอยู่ในรูปแบบใดก็ตาม (เช่น `Authorization: Bearer YOUR_API_KEY` หรือ `HTTP_AUTHORIZATION: Bearer YOUR_API_KEY`)
  • เราใช้ preg_match() เพื่อแยกส่วนของ Token (API Key) ออกจากคำว่า "Bearer" (ถ้ามี) ใน Authorization Header
  • หากไม่พบ Authorization Header เราจะตรวจสอบ HTTP_X_API_KEY แทน
  • ถ้าไม่พบ API Key ใน Header ใดๆ เลย เราจะส่ง HTTP Status Code 401 (Unauthorized) พร้อมกับ JSON Response แจ้งว่าไม่มี API Key

2. การตรวจสอบ API Key

หลังจากที่เราได้ API Key มาแล้ว ขั้นตอนต่อไปคือการตรวจสอบว่า API Key นั้นถูกต้องหรือไม่ โดยเทียบกับข้อมูลในฐานข้อมูลที่เราได้เก็บไว้ในบทที่แล้ว

สมมติว่าเรามีตารางชื่อ api_keys ในฐานข้อมูล MySQL ที่มีโครงสร้างดังนี้:

  • id (INT, PRIMARY KEY, AUTO_INCREMENT)
  • api_key (VARCHAR(255), UNIQUE)
  • user_id (INT) - ID ของผู้ใช้งานที่ API Key นี้เป็นของ
  • created_at (TIMESTAMP)

ตัวอย่างโค้ด PHP:

<?php

// ... (โค้ดส่วนของการรับ API Key จาก Header)

// เชื่อมต่อกับฐานข้อมูล (แก้ไขข้อมูลการเชื่อมต่อให้ถูกต้อง)
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "database_name";

$conn = new mysqli($servername, $username, $password, $dbname);

// ตรวจสอบการเชื่อมต่อ
if ($conn->connect_error) {
    http_response_code(500); // Internal Server Error
    echo json_encode(['message' => 'Database connection failed: ' . $conn->connect_error]);
    exit;
}

// สร้าง SQL Query เพื่อตรวจสอบ API Key
$sql = "SELECT user_id FROM api_keys WHERE api_key = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $apiKey); // "s" หมายถึง string
$stmt->execute();
$result = $stmt->get_result();

if ($result->num_rows > 0) {
    // API Key ถูกต้อง
    $row = $result->fetch_assoc();
    $userId = $row['user_id'];

    // ตอนนี้เรามี $userId ที่ API Key นี้เป็นของ
    // เราสามารถนำไปใช้ในการตรวจสอบสิทธิ์เพิ่มเติมได้
    // เช่น ตรวจสอบว่าผู้ใช้งานนี้มีสิทธิ์เข้าถึง Endpoint นี้หรือไม่

} else {
    // API Key ไม่ถูกต้อง
    http_response_code(401); // Unauthorized
    echo json_encode(['message' => 'Invalid API Key']);
    exit;
}

$stmt->close();
$conn->close();

// ถ้ามาถึงจุดนี้ แสดงว่า API Key ถูกต้อง
// ดำเนินการตาม Request ที่ได้รับ
echo json_encode(['message' => 'API Key is valid. Proceeding with request.']);

คำอธิบายโค้ด:

  • เราเชื่อมต่อกับฐานข้อมูล MySQL โดยใช้ mysqli
  • เราใช้ Prepared Statement เพื่อป้องกัน SQL Injection (สำคัญมาก!)
  • เราสร้าง SQL Query เพื่อค้นหา API Key ในตาราง api_keys
  • ถ้าพบ API Key, เราจะดึงค่า user_id มาใช้ในการตรวจสอบสิทธิ์เพิ่มเติม (ถ้าจำเป็น)
  • ถ้าไม่พบ API Key, เราจะส่ง HTTP Status Code 401 (Unauthorized) พร้อมกับ JSON Response แจ้งว่า API Key ไม่ถูกต้อง

3. การให้สิทธิ์การเข้าถึง

หลังจากที่ตรวจสอบแล้วว่า API Key ถูกต้อง เราสามารถให้สิทธิ์การเข้าถึง API ได้ โดยอาจจะอิงจาก user_id ที่เราได้จากฐานข้อมูล หรืออาจจะมี Role/Permission ที่กำหนดไว้ในฐานข้อมูล

ตัวอย่าง: สมมติว่าเรามี Endpoint สำหรับการจัดการข้อมูลสินค้า และเราต้องการให้เฉพาะผู้ใช้งานที่เป็น "Admin" เท่านั้นที่สามารถเข้าถึง Endpoint นี้ได้

<?php

// ... (โค้ดส่วนของการรับและตรวจสอบ API Key)

// หลังจากตรวจสอบ API Key แล้ว

// ตรวจสอบ Role ของผู้ใช้งาน
$sql = "SELECT role FROM users WHERE id = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $userId); // "i" หมายถึง integer
$stmt->execute();
$result = $stmt->get_result();

if ($result->num_rows > 0) {
    $row = $result->fetch_assoc();
    $userRole = $row['role'];

    if ($userRole === 'admin') {
        // ผู้ใช้งานเป็น Admin สามารถเข้าถึง Endpoint นี้ได้
        // ดำเนินการตาม Request ที่ได้รับ
        echo json_encode(['message' => 'Admin access granted. Proceeding with request.']);
    } else {
        // ผู้ใช้งานไม่ใช่ Admin ไม่สามารถเข้าถึง Endpoint นี้ได้
        http_response_code(403); // Forbidden
        echo json_encode(['message' => 'Insufficient permissions']);
        exit;
    }
} else {
    // ไม่พบผู้ใช้งานในฐานข้อมูล (อาจจะเกิดจาก API Key ที่ผิดพลาด)
    http_response_code(401); // Unauthorized
    echo json_encode(['message' => 'Invalid API Key']);
    exit;
}

$stmt->close();
$conn->close();

คำอธิบายโค้ด:

  • เราดึง Role ของผู้ใช้งานจากตาราง users โดยใช้ user_id ที่เราได้จาก API Key
  • ถ้า Role เป็น "admin" เราจะอนุญาตให้เข้าถึง Endpoint ได้
  • ถ้า Role ไม่ใช่ "admin" เราจะส่ง HTTP Status Code 403 (Forbidden) พร้อมกับ JSON Response แจ้งว่าไม่มีสิทธิ์

ข้อควรระวังและข้อผิดพลาดที่พบบ่อย

  • SQL Injection: อย่าลืมใช้ Prepared Statement เสมอเพื่อป้องกัน SQL Injection
  • การเก็บ API Key ใน Client: อย่าเก็บ API Key ไว้ใน Client-Side Code (เช่น JavaScript) เพราะจะทำให้ API Key ถูกเปิดเผยได้ง่าย ให้ใช้ Server-Side Code ในการเรียก API แทน
  • CORS: ถ้า API ของคุณถูกเรียกจาก Domain อื่น อย่าลืมตั้งค่า CORS Headers ให้ถูกต้อง
  • HTTP Status Codes: ใช้ HTTP Status Codes ให้ถูกต้องเพื่อสื่อสารสถานะของ Request ให้กับ Client อย่างชัดเจน (เช่น 401 Unauthorized, 403 Forbidden, 500 Internal Server Error)
  • การจัดการ Error: จัดการ Error อย่างเหมาะสม และส่ง Error Response ที่มีข้อมูลเพียงพอให้ Client สามารถแก้ไขปัญหาได้

สรุป

ในบทนี้ เราได้เรียนรู้วิธีการ Implement Authentication ด้วย API Key โดยการรับ API Key จาก HTTP Header, ตรวจสอบความถูกต้องของ API Key กับข้อมูลในฐานข้อมูล, และให้สิทธิ์การเข้าถึง API โดยอิงจาก API Key นอกจากนี้ เรายังได้เรียนรู้เกี่ยวกับข้อควรระวังและข้อผิดพลาดที่พบบ่อยในการ Implement Authentication ด้วย API Key

ในบทต่อไป เราจะศึกษาเกี่ยวกับ Middleware ซึ่งเป็นเครื่องมือที่มีประโยชน์ในการจัดการ Request และ Response ของ API

Office.in.th Custom Service

이 구조를 바탕으로 시스템을 개발하거나 맞춤 변경하고 싶으신가요?

Office.in.th는 엔터프라이즈 웹 애플리케이션, API 연동, 공공/민간 업무 관리 시스템을 설계·개발하며 장기 지원을 제공합니다.

소프트웨어 개발 서비스 보기