Skip to content
Grok

ประเภทของ Auth Tokens

JWT (JSON Web Token)

คือโทเคนรูปแบบ JSON ที่เข้ารหัสหรือเซ็นต์ดิจิทัล ใช้เก็บข้อมูลผู้ใช้และเมตาดาต้า

ts
// ตัวอย่างการสร้าง JWT ใน Node.js
import jwt from "jsonwebtoken";

const token = jwt.sign(
  { userId: 123, role: "admin" }, // payload
  "your-secret-key", // secret key
  { expiresIn: "1h" }, // options
);
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEyMywicm9sZSI6ImFkbWluIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE1MTYyNDI2MjJ9...

// การตรวจสอบ JWT
const decoded = jwt.verify(token, "your-secret-key");
console.log(decoded); // { userId: 123, role: 'admin', iat: 1516239022, exp: 1516242622 }
bash
JWT_SECRET=your-secret-key

OAuth 2.0 Tokens

ใช้โทเคนสองประเภทคือ Access Token (อายุสั้น) และ Refresh Token (อายุยาว)

ts
// ตัวอย่างการใช้ OAuth 2.0 ใน Next.js
import NextAuth from "next-auth";
import type { NextAuthOptions } from "next-auth";
import GoogleProvider from "next-auth/providers/google";

export const authOptions: NextAuthOptions = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
  ],
  callbacks: {
    async jwt({ token, account }) {
      // เก็บ access token และ refresh token ใน JWT
      if (account) {
        token.accessToken = account.access_token;
        token.refreshToken = account.refresh_token;
      }
      return token;
    },
    async session({ session, token }) {
      // ส่ง access token ไปยัง client
      session.accessToken = token.accessToken as string;
      return session;
    },
  },
};

export default NextAuth(authOptions);
bash
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-nextauth-secret

API Key

รหัสเฉพาะที่ใช้สำหรับยืนยันตัวตนเมื่อเรียกใช้งาน API

ts
// ตัวอย่างการใช้ API Key กับ Stripe
import Stripe from "stripe";

const stripe = new Stripe(process.env.STRIPE_API_KEY!, {
  apiVersion: "2023-10-16",
});

const createCustomer = async (): Promise<Stripe.Customer> => {
  const customer = await stripe.customers.create({
    email: "[email protected]",
    name: "John Doe",
  });
  return customer;
};

// ตัวอย่างการตรวจสอบ API Key ใน H3
import { createServer, defineEventHandler, getRequestHeaders } from "h3";

const app = createServer();

app.use(
  "/",
  defineEventHandler(async (event) => {
    const headers = getRequestHeaders(event);
    const apiKey = headers["x-api-key"];

    if (!apiKey || apiKey !== process.env.API_KEY) {
      return { statusCode: 401, body: { error: "Unauthorized" } };
    }

    // ดำเนินการต่อหลังจากตรวจสอบ API Key
    return { statusCode: 200, body: { message: "Authenticated" } };
  }),
);
bash
STRIPE_API_KEY=sk_test_51NZKHVLYgESNIbH0Usd...
API_KEY=your-api-key

Session Token

โทเคนที่สร้างและเก็บบนเซิร์ฟเวอร์ ใช้ร่วมกับคุกกี้

ts
// ตัวอย่างการใช้ Session ใน H3
import { randomUUID } from "crypto";
import {
  createApp,
  createServer,
  defineEventHandler,
  parseCookies,
  setCookie,
} from "h3";

const app = createApp();
const sessions = new Map();

// Middleware สำหรับตรวจสอบ session
const authMiddleware = defineEventHandler(async (event) => {
  const cookies = parseCookies(event);
  const sessionId = cookies.sessionId;

  if (sessionId && sessions.has(sessionId)) {
    // มี session อยู่แล้ว
    event.context.session = sessions.get(sessionId);
  } else {
    // ไม่มี session
    event.context.session = null;
  }
});

// Route สำหรับ login
app.use(
  "/login",
  defineEventHandler(async (event) => {
    // สมมติว่ามีการตรวจสอบข้อมูลผู้ใช้
    const validUser = true;

    if (validUser) {
      const sessionId = randomUUID();
      const sessionData = {
        userId: 123,
        isAuthenticated: true,
        createdAt: Date.now(),
      };

      sessions.set(sessionId, sessionData);

      setCookie(event, "sessionId", sessionId, {
        httpOnly: true,
        secure: true,
        maxAge: 24 * 60 * 60, // 1 วัน
        path: "/",
      });

      return { redirect: "/dashboard" };
    }

    return { error: "Invalid credentials" };
  }),
);

// Route สำหรับดูข้อมูลผู้ใช้
app.use(
  "/profile",
  defineEventHandler(async (event) => {
    await authMiddleware(event);

    if (!event.context.session || !event.context.session.isAuthenticated) {
      return { redirect: "/login" };
    }

    // แสดงข้อมูลผู้ใช้
    return { userId: event.context.session.userId };
  }),
);
bash
SESSION_SECRET=your-session-secret

SAML Assertion

ใช้ในระบบ B2B และองค์กรใหญ่ที่ต้องการความปลอดภัยสูง

ts
// ตัวอย่างการใช้ SAML กับ WorkOS และ H3
import { WorkOS } from "@workos-inc/node";
import { createServer, defineEventHandler } from "h3";

const app = createServer();
const workos = new WorkOS(process.env.WORKOS_API_KEY!);

// ตัวอย่างการสร้าง SAML Connection
app.use(
  "/auth/sso",
  defineEventHandler(async (event) => {
    const authorizationURL = workos.sso.getAuthorizationURL({
      domain: "acme.com",
      redirectURI: "https://example.com/callback",
    });

    return { statusCode: 302, headers: { Location: authorizationURL } };
  }),
);

// ตัวอย่างการรับ SAML Response
app.use(
  "/callback",
  defineEventHandler(async (event) => {
    const query = getQuery(event);
    const code = query.code as string;

    const { profile } = await workos.sso.getProfileAndToken({
      code,
      clientID: process.env.WORKOS_CLIENT_ID!,
    });

    // สร้าง session ด้วยข้อมูลจาก SAML
    const sessionId = randomUUID();
    sessions.set(sessionId, { user: profile });

    setCookie(event, "sessionId", sessionId, {
      httpOnly: true,
      secure: true,
      maxAge: 24 * 60 * 60,
      path: "/",
    });

    return { statusCode: 302, headers: { Location: "/dashboard" } };
  }),
);
bash
WORKOS_API_KEY=your-workos-api-key
WORKOS_CLIENT_ID=your-workos-client-id

Bearer Token

โทเคนที่ส่งในส่วนหัว Authorization ของ HTTP Request

ts
// ตัวอย่างการใช้ Bearer Token ใน Next.js และ H3
// client-side
import { useEffect, useState } from "react";

interface ProtectedData {
  data: string;
}

const fetchProtectedData = async (): Promise<ProtectedData> => {
  const res = await fetch("/api/protected", {
    headers: {
      "Authorization": `Bearer ${localStorage.getItem("token")}`,
    },
  });
  return res.json();
};

// server-side (H3 API handler)
import { createServer, defineEventHandler, getRequestHeaders } from "h3";
import jwt from "jsonwebtoken";

interface DecodedToken {
  userId: number;
  role: string;
}

const app = createServer();

app.use(
  "/api/protected",
  defineEventHandler(async (event) => {
    const headers = getRequestHeaders(event);
    const authHeader = headers.authorization;

    if (!authHeader || !authHeader.startsWith("Bearer ")) {
      return { statusCode: 401, body: { message: "Unauthorized" } };
    }

    const token = authHeader.split(" ")[1];

    try {
      // ตรวจสอบ token
      const decoded = jwt.verify(
        token,
        process.env.JWT_SECRET!,
      ) as DecodedToken;
      // ดำเนินการต่อ
      return { statusCode: 200, body: { data: "Protected data" } };
    } catch (error) {
      return { statusCode: 401, body: { message: "Invalid token" } };
    }
  }),
);
bash
JWT_SECRET=your-jwt-secret