Now.js Framework Documentation

Now.js Framework Documentation

SecurityManager

TH 04 Sep 2026 01:40

SecurityManager

ภาพรวม

SecurityManager คือระบบจัดการความปลอดภัยใน Now.js Framework รองรับ CSRF, JWT, Rate Limiting และ Content Security Policy

ใช้เมื่อ:

  • ต้องการป้องกัน CSRF attacks
  • ต้องการจัดการ JWT tokens
  • ต้องการ rate limiting
  • ต้องการ input sanitization
  • ต้องการ CSP management

ทำไมต้องใช้:

  • ✅ CSRF protection (token-based)
  • ✅ JWT management (validate, refresh)
  • ✅ Rate limiting (per endpoint)
  • ✅ Input sanitization (XSS prevention)
  • ✅ Content Security Policy
  • ✅ HTTP interceptors
  • ✅ Form protection

การใช้งานพื้นฐาน

Initialization

await SecurityManager.init({
  csrf: {
    enabled: true,
    tokenName: '_token',
    headerName: 'X-CSRF-Token'
  },
  jwt: {
    enabled: true,
    storageName: 'auth_token',
    autoRefresh: true
  },
  rateLimit: {
    enabled: true,
    globalLimit: 100,
    windowMs: 15 * 60 * 1000 // 15 minutes
  }
});

CSRF Protection

Auto-inject in Forms

<form action="/api/submit" method="POST">
  <!-- CSRF token จะถูก inject อัตโนมัติ -->
  <input type="text" name="email">
  <button type="submit">Submit</button>
</form>

Get CSRF Token

const token = SecurityManager.getCSRFToken();
console.log(token); // 'abc123...'

Manual CSRF in Requests

// SecurityManager จะ inject อัตโนมัติใน ApiService
await ApiService.post('/api/data', {
  name: 'John'
});
// Request จะมี X-CSRF-Token header อัตโนมัติ

Refresh CSRF Token

await SecurityManager.refreshCSRFToken();

JWT Management

Get JWT Token

const token = SecurityManager.getJWTToken();

Validate Token

const isValid = SecurityManager.validateJWTToken(token);
if (!isValid) {
  // Token expired or invalid
  redirectToLogin();
}

Refresh Token

await SecurityManager.refreshJWTToken();

Clear Token (Logout)

SecurityManager.clearJWTToken();

Auto-refresh Token

SecurityManager.init({
  jwt: {
    enabled: true,
    autoRefresh: true,
    refreshThreshold: 5 * 60 * 1000 // Refresh 5 mins before expiry
  }
});

Rate Limiting

Check Rate Limit

const result = SecurityManager.checkRateLimit('/api/login');

if (!result.allowed) {
  console.log(`Rate limited. Retry after ${result.retryAfter}ms`);
}

Per-Endpoint Limits

SecurityManager.init({
  rateLimit: {
    enabled: true,
    globalLimit: 100,
    perEndpoint: {
      '/api/login': { limit: 5, windowMs: 60000 },    // 5 per minute
      '/api/register': { limit: 3, windowMs: 60000 }, // 3 per minute
      '/api/upload': { limit: 10, windowMs: 300000 }  // 10 per 5 minutes
    }
  }
});

Input Sanitization

Sanitize Input

// ป้องกัน XSS
const safeInput = SecurityManager.sanitizeInput(userInput);
// '<script>alert("xss")</script>' => '&lt;script&gt;alert("xss")&lt;/script&gt;'

Sanitize Object

const safeData = SecurityManager.sanitizeRequestData({
  name: '<script>alert("xss")</script>',
  email: 'user@example.com'
});
// { name: '&lt;script&gt;...', email: 'user@example.com' }

Content Security Policy

CSP Configuration

SecurityManager.init({
  csp: {
    enabled: true,
    directives: {
      'default-src': ["'self'"],
      'script-src': ["'self'", "'unsafe-inline'"],
      'style-src': ["'self'", "'unsafe-inline'"],
      'img-src': ["'self'", "data:", "https:"],
      'connect-src': ["'self'"],
      'frame-src': ["'none'"],
      'object-src': ["'none'"]
    }
  }
});

CSP Violation Reporting

SecurityManager.init({
  csp: {
    enabled: true,
    reportUri: '/api/csp-report'
  }
});

// Listen for violations
EventManager.on('csp:violation', (violation) => {
  console.log('CSP Violation:', violation);
});

การตั้งค่า

await SecurityManager.init({
  // CSRF
  csrf: {
    enabled: true,
    tokenName: '_token',
    headerName: 'X-CSRF-Token',
    cookieName: 'XSRF-TOKEN',
    tokenUrl: '/api/auth/csrf-token',
    autoRefresh: true,
    refreshInterval: 30 * 60 * 1000 // 30 minutes
  },

  // JWT
  jwt: {
    enabled: true,
    cookieName: 'auth_token',
    refreshCookieName: 'refresh_token',
    storageKey: 'auth_jwt',              // ดูหมายเหตุด้านล่าง
    autoRefresh: true,
    refreshBeforeExpiry: 5 * 60 * 1000,  // 5 นาที
    refreshEndpoint: 'api/auth/refresh',
    validateSignature: true,
    algorithm: 'HS256',
    issuer: window.location.hostname,
    audience: window.location.hostname
  },

  // Rate Limiting
  rateLimit: {
    enabled: true,
    storage: 'memory',
    globalLimit: 100,
    windowMs: 15 * 60 * 1000,
    perEndpoint: {}
  },

  // CSP
  csp: {
    enabled: false,
    directives: {}
  }
});

jwt.storageKey ต้องไม่ชนกับ token.storageKey ของ AuthManager
ค่าเริ่มต้นคือ 'auth_jwt' เก็บ สตริง JWT ส่วน AuthManager เก็บ
โปรไฟล์ผู้ใช้ (ออบเจ็กต์ JSON) ไว้ที่ 'auth_user' เดิมทั้งคู่ตั้งค่า
เริ่มต้นเป็น 'auth_user' เหมือนกัน ทำให้ initJWT() อ่านโปรไฟล์ขึ้นมา
ตรวจว่าไม่ใช่ JWT แล้ว clearJWTToken() ก็ลบทิ้งทุกครั้งที่โหลดหน้า
โปรไฟล์ที่แคชไว้จึงไม่เคยอยู่รอด และแอปเปิดตอนออฟไลน์ไม่ได้
ถ้าแอปของคุณเขียน JWT ลง 'auth_user' เอง ให้ย้ายไป 'auth_jwt'
(หรือกำหนด storageKey เป็นคีย์อื่นของคุณเอง) ตอนอัปเกรด
ทั้งนี้ในการใช้งานปกติ token จริงอยู่ใน httpOnly cookie คีย์นี้จึงแทบไม่ถูกใช้

API อ้างอิง

CSRF Methods

SecurityManager.getCSRFToken()

รับ CSRF token ปัจจุบัน

Returns: string|null

SecurityManager.refreshCSRFToken()

Refresh CSRF token จาก server

Returns: Promise<string>

SecurityManager.injectCSRFIntoForm(form, token?)

Inject CSRF token ใน form

Parameter Type Description
form HTMLFormElement Form element

JWT Methods

SecurityManager.getJWTToken()

รับ JWT token

Returns: string|null

SecurityManager.validateJWTToken(token)

Validate JWT token

Parameter Type Description
token string JWT token

Returns: boolean

SecurityManager.refreshJWTToken()

Refresh JWT token

Returns: Promise<string>

SecurityManager.clearJWTToken()

Clear JWT token (logout)

Rate Limit Methods

SecurityManager.checkRateLimit(endpoint, identifier?)

ตรวจสอบ rate limit

Parameter Type Description
endpoint string API endpoint
identifier string User identifier (optional)

Returns: Object:

{
  allowed: boolean,
  remaining: number,
  resetTime: number,
  retryAfter: number
}

Sanitization Methods

SecurityManager.sanitizeInput(value)

Sanitize input string

Parameter Type Description
value string Input value

Returns: string - Sanitized value

SecurityManager.sanitizeRequestData(data)

Sanitize object/array recursively

Parameter Type Description
data object/array Data to sanitize

Returns: object/array - Sanitized data

Data Attributes

Attribute คำอธิบาย
data-csrf ใส่บน <form> ตั้ง false หรือ disabled เพื่อไม่ให้แนบ CSRF token กับฟอร์มนั้น

เหตุการณ์

Event เมื่อเกิด Detail
security:initialized init() เสร็จ {csrf, jwt}
csrf:refreshed ได้ CSRF token ใหม่ {token}
csrf:retry เจอ CSRF ไม่ผ่าน (419) กำลังให้โอกาสส่งซ้ำ {token}
jwt:refreshed ได้ JWT ใหม่ {token}
jwt:cleared ลบ JWT ที่เก็บไว้ ไม่มี
csp:violation เบราว์เซอร์รายงานการละเมิด CSP {directive, uri, source, line, timestamp} (ส่งตรง ไม่ห่อ)
security:error เกิดข้อผิดพลาดด้านความปลอดภัย {message, error}
security:destroyed destroy() เสร็จ ไม่มี

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

Protected API Calls

// SecurityManager จะ inject headers อัตโนมัติ
async function saveProfile(data) {
  try {
    // CSRF และ JWT headers จะถูกเพิ่มอัตโนมัติ
    await ApiService.put('/api/profile', data);
    NotificationManager.success('บันทึกแล้ว');
  } catch (error) {
    if (error.status === 419) {
      // CSRF token expired
      await SecurityManager.refreshCSRFToken();
      // Retry
      return saveProfile(data);
    }
    throw error;
  }
}

Login with Rate Limiting

async function login(email, password) {
  // Check rate limit
  const limit = SecurityManager.checkRateLimit('/api/login');
  if (!limit.allowed) {
    throw new Error(`ลองอีกครั้งใน ${Math.ceil(limit.retryAfter / 1000)} วินาที`);
  }

  const response = await ApiService.post('/api/login', {
    email: SecurityManager.sanitizeInput(email),
    password
  });

  return response;
}

Form with CSRF Protection

<form id="contact-form" action="/api/contact" method="POST" data-security>
  <input type="text" name="name" required>
  <input type="email" name="email" required>
  <textarea name="message" required></textarea>
  <button type="submit">ส่งข้อความ</button>
</form>

<script>
// SecurityManager จะ:
// 1. Inject CSRF token
// 2. Sanitize inputs
// 3. Check rate limit
// ... อัตโนมัติ
</script>

ข้อควรระวัง

⚠️ 1. Enable CSRF สำหรับ Production

// ❌ CSRF disabled in production
SecurityManager.init({ csrf: { enabled: false } });

// ✅ Enable CSRF
SecurityManager.init({ csrf: { enabled: true } });

⚠️ 2. JWT Token ใน Memory

// ❌ ไม่ควรเก็บ JWT ใน localStorage สำหรับข้อมูลสำคัญมาก
jwt: { storageType: 'localStorage' }

// ✅ ใช้ memory หรือ httpOnly cookie
jwt: { storageType: 'memory' }

⚠️ 3. Sanitize User Input

// ❌ ใช้ user input โดยตรง
element.innerHTML = userInput;

// ✅ Sanitize ก่อน
element.innerHTML = SecurityManager.sanitizeInput(userInput);

// หรือใช้ textContent
element.textContent = userInput;

เอกสารที่เกี่ยวข้อง