บทนำ

การนำ AI API มาใช้งานในแอปพลิเคชัน Frontend นั้นสะดวกและรวดเร็ว แต่หากไม่ระวัง คุณอาจสร้างช่องโหว่ด้านความปลอดภัยที่ทำให้ API Key รั่วไหลไปยังผู้ไม่หวังดีได้โดยไม่รู้ตัว บทความนี้จะอธิบาย 3 รูปแบบสถาปัตยกรรมที่ช่วยป้องกันปัญหานี้ พร้อมตัวอย่างโค้ดที่นำไปใช้งานได้จริง ---

ทำไม API Key ถึงต้องป้องกัน?

เมื่อคุณฝัง API Key ไว้ในโค้ด Frontend ไม่ว่าจะเป็น React, Vue, หรือ Angular ผู้ใช้งานทุกคนสามารถเปิด Developer Tools ดู Network Tab หรือ Source Code แล้วค้นหา Key ของคุณได้ทันที นี่คือปัญหาพื้นฐานที่ต้องแก้ไขตั้งแต่ต้น ---

รูปแบบที่ 1: Backend Proxy (สถาปัตยกรรมแนะนำ)

แนวคิด

แทนที่จะเรียก API ตรงจาก Frontend ให้ Frontend ส่งคำขอไปยัง Backend Server ของตัวเองก่อน แล้วให้ Backend ไปเรียก AI API อีกที วิธีนี้ทำให้ API Key อยู่เฉพาะใน Backend เท่านั้น

ข้อดี

- API Key ไม่มีทางถูกเปิดเผยใน Client Side เลย - สามารถทำ Caching, Rate Limiting และ Logging ได้ง่าย - ปรับแต่ง Request/Response ได้ตามต้องการ

ข้อเสีย

- เพิ่ม Latency จากการผ่าน Middleware - ต้องดูแล Server เพิ่มขึ้น

ตัวอย่างโค้ด Backend (Node.js/Express)

// server.js
import express from 'express';
import axios from 'axios';

const app = express();
app.use(express.json());

// API Key อยู่เฉพาะใน Backend เท่านั้น
const HOLYSHEEP_API_KEY = process.env.HOLYSHEEP_API_KEY;
const HOLYSHEEP_BASE_URL = 'https://api.holysheep.ai/v1';

app.post('/api/chat', async (req, res) => {
  try {
    const { messages } = req.body;
    
    const response = await axios.post(
      ${HOLYSHEEP_BASE_URL}/chat/completions,
      {
        model: 'gpt-4.1',
        messages: messages
      },
      {
        headers: {
          'Authorization': Bearer ${HOLYSHEEP_API_KEY},
          'Content-Type': 'application/json'
        },
        timeout: 30000
      }
    );
    
    res.json(response.data);
  } catch (error) {
    console.error('Proxy error:', error.message);
    res.status(500).json({ error: 'Internal server error' });
  }
});

app.listen(3000, () => {
  console.log('Proxy server running on port 3000');
});

ตัวอย่างโค้ด Frontend (React)

// apiService.js
const API_BASE = '/api';

export async function sendChat(messages) {
  const response = await fetch(${API_BASE}/chat, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ messages })
  });
  
  if (!response.ok) {
    throw new Error('Request failed');
  }
  
  return response.json();
}
---

รูปแบบที่ 2: Cloudflare Workers / Edge Functions

แนวคิด

ใช้ Edge Functions เป็นตัวกลางระหว่าง Frontend และ AI API ซึ่งทำงานบน Edge Network ใกล้ผู้ใช้งาน ทำให้ได้ Latency ต่ำกว่า Traditional Backend และ API Key ยังคงถูกซ่อนไว้

ข้อดี

- Latency ต่ำกว่า Traditional Backend - Scale ได้อัตโนมัติโดยไม่ต้องจัดการ Server - มี DDoS Protection และ SSL Termination ในตัว

ข้อเสีย

- ต้องเรียนรู้ Platform ใหม่ (Cloudflare Workers, Vercel Edge Functions) - มีข้อจำกัดด้าน Cold Start และ Execution Time

ตัวอย่างโค้ด Cloudflare Workers

// worker.js
export default {
  async fetch(request, env) {
    if (request.method !== 'POST') {
      return new Response('Method not allowed', { status: 405 });
    }

    try {
      const { messages } = await request.json();
      
      const response = await fetch('https://api.holysheep.ai/v1/chat/completions', {
        method: 'POST',
        headers: {
          'Authorization': Bearer ${env.HOLYSHEEP_API_KEY},
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          model: 'gpt-4.1',
          messages: messages
        })
      });

      const data = await response.json();
      return new Response(JSON.stringify(data), {
        headers: { 'Content-Type': 'application/json' }
      });
    } catch (error) {
      return new Response(JSON.stringify({ error: error.message }), {
        status: 500,
        headers: { 'Content-Type': 'application/json' }
      });
    }
  }
};

wrangler.toml

name = "ai-proxy-worker"
main = "worker.js"
compatibility_date = "2024-01-01"

[vars]
ALLOWED_ORIGIN = "https://yourdomain.com"
---

รูปแบบที่ 3: API Gateway with Key Rotation

แนวคิด

ใช้ API Gateway เป็นตัวจัดการ API Key ทั้งหมด รวมถึงการหมุนคีย์อัตโนมัติ (Automatic Key Rotation) เพื่อลดความเสี่ยงหากคีย์ใดรั่วไหล

ข้อดี

- จัดการ Key ได้จากที่เดียวทั้งหมด - หมุนคีย์ได้อัตโนมัติโดยไม่ต้อง Deploy ใหม่ - มีระบบ Logging และ Monitoring ในตัว

ข้อเสีย

- ต้องใช้บริการ Third-party (มีค่าใช้จ่ายเพิ่มเติม) - ซับซ้อนในการตั้งค่าเริ่มต้น

ตัวอย่างการตั้งค่า AWS API Gateway

# api-gateway-config.yaml
Resources:
  ProxyResource:
    Type: AWS::ApiGateway::Resource
    Properties:
      RestApiId: !Ref RESTAPI
      ParentId: !GetAtt RESTAPI.RootResourceId
      PathPart: 'ai-proxy'

  ProxyMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      RestApiId: !Ref RESTAPI
      ResourceId: !Ref ProxyResource
      HttpMethod: POST
      AuthorizationType: NONE
      Integration:
        Type: HTTP_PROXY
        Uri: https://api.holysheep.ai/v1/chat/completions
        IntegrationHttpMethod: POST

  APIKey:
    Type: AWS::ApiGateway::ApiKey
    Properties:
      Name: holy-sheep-api-key
      Enabled: true

  UsagePlan:
    Type: AWS::ApiGateway::UsagePlan
    Properties:
      ApiStages:
        - ApiId: !Ref RESTAPI
          Stage: prod
      Quota:
        Limit: 1000000
        Period: MONTH

การหมุนคีย์อัตโนมัติ (Python Script)

# rotate_key.py
import os
import requests
import boto3
from datetime import datetime, timedelta

def rotate_api_key():
    """
    หมุนคีย์เก่าและสร้างคีย์ใหม่
    ควรตั้งเป็น Cron Job รันทุก 30 วัน
    """
    # ดึงคีย์เก่าจาก Secrets Manager
    secret_name = "holy-sheep-api-key"
    region_name = "us-east-1"
    
    session = boto3.session.Session()
    client = session.client('secretsmanager', region_name=region_name)
    
    try:
        old_key = client.get_secret_value(SecretId=secret_name)
        old_key_value = old_key['SecretString']
        
        # สร้างคีย์ใหม่ (จาก HolySheep Dashboard)
        new_key = create_holysheep_key()
        
        # อัพเดท Secrets Manager
        client.put_secret_value(
            SecretId=secret_name,
            SecretString=new_key
        )
        
        # ยกเลิกคีย์เก่า
        revoke_holysheep_key(old_key_value)
        
        print(f"Key rotated successfully at {datetime.now()}")
        
    except Exception as e:
        print(f"Rotation failed: {e}")
        raise

def create_holysheep_key():
    """สร้าง API Key ใหม่จาก HolySheep"""
    response = requests.post(
        'https://api.holysheep.ai/v1/keys',
        headers={'Authorization': 'Bearer YOUR_ADMIN_KEY'}
    )
    return response.json()['api_key']

def revoke_holysheep_key(key):
    """ยกเลิก API Key เก่า"""
    requests.delete(
        f'https://api.holysheep.ai/v1/keys/{key}',
        headers={'Authorization': 'Bearer YOUR_ADMIN_KEY'}
    )

if __name__ == '__main__':
    rotate_api_key()
---

เปรียบเทียบ 3 รูปแบบ

| รูปแบบ | ความปลอดภัย | Latency | ความซับซ้อน | ค่าใช้จ่าย | |--------|-------------|---------|-------------|-----------| | Backend Proxy | สูงมาก | ปานกลาง | ปานกลาง | Server Hosting | | Edge Functions | สูง | ต่ำ | ต่ำ | Pay-per-use | | API Gateway | สูงมาก | ปานกลาง | สูง | Monthly Fee | ---

คำแนะนำในการเลือกรูปแบบ

**เลือก Backend Proxy** หากคุณมี Backend Team และต้องการควบคุม Logic ทั้งหมดเอง **เลือก Edge Functions** หากคุณต้องการ Latency ต่ำและไม่อยากดูแล Server **เลือก API Gateway** หากคุณต้องการ Enterprise-grade Security และมีงบประมาณรองรับ ---

ข้อผิดพลาดที่พบบ่อยและวิธีแก้ไข

ข้อผิดพลาดที่ 1: ฝัง API Key ไว้ใน JavaScript Bundle

**อาการ:** เปิด DevTools หรือ Source Map แล้วเจอ API Key อยู่ในโค้ด **สาเหตุ:** การใช้ Environment Variable ผิดวิธี เช่น const API_KEY = "sk-xxx" ตรงๆ **วิธีแก้ไข:**
// ผิด ❌
const API_KEY = "sk-abc123def456";

// ถูกต้อง ✅ - ส่งผ่าน Proxy แทน
const response = await fetch('/api/chat', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ messages })
});
**หลักการ:** Frontend ต้องส่ง Request ไปที่ Backend ของตัวเองเท่านั้น อย่าเรียก AI API ตรง ---

ข้อผิดพลาดที่ 2: ใส่ API Key ใน .env File แล้ว Commit lên GitHub

**อาการ:** ตรวจสอบ GitHub History แล้วเจอ API Key ที่ถูก Commit ไปแล้ว **สาเหตุ:** ไม่ได้เพิ่ม .env ใน .gitignore หรือ Commit โดยไม่ตรวจสอบ **วิธีแก้ไข:**
# สร้างไฟล์ .gitignore
echo "HOLYSHEEP_API_KEY=.env" >> .gitignore
echo ".env" >> .gitignore
echo ".env.local" >> .gitignore
echo ".env.production" >> .gitignore

ลบ API Key ที่ Commit ไปแล้วออกจาก History

git filter-branch --force --index-filter \ "git rm --cached --ignore-unmatch .env" \ --prune-empty --tag-name-filter cat -- --all

หมุนคีย์ทันทีหลังจาก Commit โดน Leak

เพราะ GitHub History อาจถูก Clone ไปแล้ว

**หลักการ:** ป้องกันที่ต้นทางด้วย .gitignore และเตรียมแผนหมุนคีย์ฉุกเฉินเสมอ ---

ข้อผิดพลาดที่ 3: ไม่ตรวจสอบ Origin/Referer Header

**อาการ:** API Key ถูกใช้งานจาก Domain อื่นที่ไม่ใช่ของเรา **สาเหตุ:** Proxy Server ไม่ได้ตรวจสอบว่า Request มาจากที่ไหน **วิธีแก้ไข:** ```javascript // server.js - เพิ่มการตรวจสอบ Origin const ALLOWED_ORIGINS = [ 'https://yourdomain.com', 'https://www.yourdomain.com', 'http://localhost:3000' // สำหรับ Development ]; app.use((req, res, next) => { const origin = req.headers.origin; if (ALLOWED_ORIGINS.includes(origin)) { res.setHeader('Access-Control-Allow-Origin', origin); } // ตรว