วิธีใช้ Better Auth API เพื่อการยืนยันตัวตนยุคใหม่

Ashley Goolam

Ashley Goolam

14 November 2025

วิธีใช้ Better Auth API เพื่อการยืนยันตัวตนยุคใหม่

Apidog สำหรับองค์กร

การติดตั้งแบบ On-Premises

SSO & RBAC

รองรับมาตรฐาน SOC 2

สำรวจ Apidog Enterprise

การยืนยันตัวตนเป็นรากฐานสำคัญของเว็บแอปพลิเคชันสมัยใหม่ แต่การตั้งค่าก็ยังคงเป็นหนึ่งในความท้าทายที่ใช้เวลานานที่สุดที่นักพัฒนาต้องเผชิญ ขอแนะนำ Better Auth API—โซลูชันการยืนยันตัวตนที่ไม่ขึ้นกับเฟรมเวิร์ก ซึ่งสัญญาว่าจะเปลี่ยนแปลงวิธีการจัดการผู้ใช้ของเรา ในคู่มือฉบับสมบูรณ์นี้ เราจะพาคุณสร้างแอปพลิเคชันแบบฟูลสแต็กที่สมบูรณ์ ซึ่งแสดงให้เห็นถึงพลังและความเรียบง่ายของ Better Auth โดยใช้ Bun เพื่อประสิทธิภาพที่รวดเร็วเป็นพิเศษ

💡
ต้องการเครื่องมือทดสอบ API ที่ยอดเยี่ยมที่สร้าง เอกสาร API ที่สวยงาม หรือไม่?

ต้องการแพลตฟอร์มแบบ All-in-One ที่รวมเข้าด้วยกันสำหรับทีมพัฒนาของคุณเพื่อทำงานร่วมกันด้วย ประสิทธิภาพสูงสุด หรือไม่?

Apidog ตอบสนองทุกความต้องการของคุณ และ มาแทนที่ Postman ในราคาที่ย่อมเยากว่ามาก!
ปุ่ม

Better Auth API คืออะไร?

Better Auth API เป็นเฟรมเวิร์กการยืนยันตัวตนแบบโอเพนซอร์สที่ทันสมัย ออกแบบมาเพื่อทำงานร่วมกันได้อย่างราบรื่นในทุกสภาพแวดล้อม JavaScript ไม่เหมือนกับไลบรารีการยืนยันตัวตนแบบดั้งเดิมที่จำกัดคุณให้อยู่ในระบบนิเวศเฉพาะ Better Auth มอบ API แบบรวมศูนย์ที่ปรับให้เข้ากับสแต็กของคุณ ไม่ว่าคุณจะใช้ React, Vue, Svelte หรือ vanilla JavaScript บนส่วนหน้า และ Node.js, Bun หรือ Deno บนส่วนหลัง สถาปัตยกรรมที่ใช้ปลั๊กอินรองรับกลยุทธ์การยืนยันตัวตนที่หลากหลาย ตั้งแต่การใช้รหัสผ่าน/อีเมลแบบดั้งเดิม ไปจนถึงผู้ให้บริการ OAuth, passkeys และ magic links ทั้งหมดนี้ยังคงรักษาความปลอดภัยของประเภทข้อมูลและประสบการณ์นักพัฒนาที่ยอดเยี่ยม

เบทเทอร์ ออธ

เริ่มต้นใช้งาน Better Auth: ข้อกำหนดเบื้องต้นและการตั้งค่าโปรเจกต์

ก่อนที่จะลงมือเขียนโค้ด ตรวจสอบให้แน่ใจว่าคุณได้ติดตั้งสิ่งต่อไปนี้แล้ว:

VS Code IDE

แม้ว่าการตั้งค่านี้จะทำงานได้อย่างสมบูรณ์แบบกับ npm แต่เราจะสาธิตขั้นตอนการทำงานของ Bun ซึ่งมีการติดตั้งแพ็คเกจที่เร็วกว่า 3-5 เท่า และประสบการณ์การพัฒนาที่ราบรื่นยิ่งขึ้น

การสร้างโปรเจกต์ตัวอย่าง: การนำไปใช้งานทีละขั้นตอน

มาสร้างระบบยืนยันตัวตนที่ใช้งานได้จริงด้วยส่วนหน้า React และส่วนหลัง Express พร้อมด้วยการคงอยู่ของข้อมูลในฐานข้อมูล

ขั้นตอนที่ 1: การตั้งค่าส่วนหลังด้วย Express และ Drizzle ORM

1. เริ่มต้นโปรเจกต์ส่วนหลัง

ขั้นแรก สร้างและเข้าสู่ไดเรกทอรีส่วนหลังของคุณ:

mkdir better-auth-backend
cd better-auth-backend
bun init -y

2. ติดตั้ง Dependencies

เราจะต้องใช้ Express สำหรับเซิร์ฟเวอร์, Better Auth สำหรับการยืนยันตัวตน และ Drizzle ORM สำหรับการจัดการฐานข้อมูล:

bun add express better-auth drizzle-orm
bun add -D @types/bun @types/express drizzle-kit

3. กำหนดค่าตัวแปรสภาพแวดล้อม

สร้างไฟล์ .env เพื่อเก็บการกำหนดค่าที่ละเอียดอ่อน:

BETTER_AUTH_SECRET=your-secret-key-here # Generate with: openssl rand -base64 32
BETTER_AUTH_URL=http://localhost:3000
DATABASE_URL=local.db

*BETTER_AUTH_SECRET* สามารถสร้างได้จากเว็บไซต์ better-auth

4. สร้าง Database Schema ด้วย Drizzle ORM

Better Auth ทำงานได้ดีที่สุดกับ Drizzle ซึ่งให้การรองรับ TypeScript ที่ยอดเยี่ยมและหลีกเลี่ยงปัญหาโมดูลเนทีฟ สร้าง src/db/schema.ts:

import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";

export const user = sqliteTable("user", {
  id: text("id").primaryKey(),
  name: text('name').notNull(),
  email: text('email').notNull().unique(),
  emailVerified: integer('email_verified', { mode: 'boolean' }).notNull().default(false),
  image: text('image'),
  createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
  updatedAt: integer('updated_at', { mode: 'timestamp' }).notNull(),
});

export const session = sqliteTable("session", {
  id: text("id").primaryKey(),
  expiresAt: integer('expires_at', { mode: 'timestamp' }).notNull(),
  token: text('token').notNull().unique(),
  createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
  userId: text('user_id').notNull(),
});

export const account = sqliteTable("account", {
  id: text("id").primaryKey(),
  accountId: text('account_id').notNull(),
  providerId: text('provider_id').notNull(),
  userId: text('user_id').notNull(),
  accessToken: text('access_token'),
  refreshToken: text('refresh_token'),
  createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
});

export const verification = sqliteTable("verification", {
  id: text("id").primaryKey(),
  identifier: text('identifier').notNull(),
  value: text('value').notNull(),
  expiresAt: integer('expires_at', { mode: 'timestamp' }).notNull(),
});

5. กำหนดค่าการเชื่อมต่อฐานข้อมูล

สร้าง src/db/index.ts โดยใช้การผูก SQLite ดั้งเดิมของ Bun:

import { Database } from "bun:sqlite";
import { drizzle } from "drizzle-orm/bun-sqlite";

const sqlite = new Database("local.db");
export const db = drizzle(sqlite);

6. ตั้งค่าการกำหนดค่า Better Auth

สร้าง src/lib/auth.ts เพื่อกำหนดค่า Better Auth API:

import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { db } from "../db";
import { user, session, account, verification } from "../db/schema";

export const auth = betterAuth({
  database: drizzleAdapter(db, {
    provider: "sqlite",
    schema: {
      user: user,
      session: session,
      account: account,
      verification: verification,
    },
  }),
  emailAndPassword: {
    enabled: true,
  },
  trustedOrigins: ["http://localhost:5173"],
});

7. สร้าง Express Server

ใน src/index.ts ให้เมานต์ตัวจัดการ Better Auth API:

import express from "express";
import cors from "cors";
import { toNodeHandler } from "better-auth/node";
import { auth } from "./lib/auth";

const app = express();
const PORT = process.env.PORT || 3000;

app.use(
  cors({
    origin: "http://localhost:5173",
    credentials: true,
  })
);

// Mount Better Auth API at /api/auth
app.use("/api/auth", toNodeHandler(auth));
app.use(express.json());

app.get("/api/me", async (req, res) => {
  const session = await auth.api.getSession({
    headers: req.headers,
  });
  
  if (!session) {
    return res.status(401).json({ error: "Unauthorized" });
  }
  
  res.json({ user: session.user });
});

app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
});

8. เรียกใช้ Database Migration

สร้าง drizzle.config.ts ในรูทของส่วนหลัง:

import { defineConfig } from "drizzle-kit";

export default defineConfig({
  dialect: "sqlite",
  schema: "./src/db/schema.ts",
  out: "./drizzle",
  dbCredentials: {
    url: "local.db",
  },
});

ดำเนินการ migration เพื่อสร้างตาราง:

bunx drizzle-kit push
โครงสร้างโปรเจกต์เซิร์ฟเวอร์ส่วนหลัง

ขั้นตอนที่ 2: การตั้งค่าส่วนหน้าด้วย React และ Vite

1. สร้างแอปพลิเคชัน React

ในเทอร์มินัลใหม่ เริ่มต้นส่วนหน้า:

bun create vite better-auth-frontend --template react-ts
cd better-auth-frontend

2. ติดตั้ง Dependencies

bun add better-auth

3. กำหนดค่า Tailwind CSS (อัปเดต V4)

Tailwind CSS v4 ต้องการการตั้งค่าที่แตกต่างกัน ติดตั้งแพ็คเกจใหม่:

bun add -D tailwindcss postcss @tailwindcss/postcss

สร้าง tailwind.config.js ในรูทของโปรเจกต์:

/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

สร้าง postcss.config.js:

export default {
  plugins: {
    "@tailwindcss/postcss": {},
  },
}

สร้าง src/index.css:

@import "tailwindcss";

body {
  margin: 0;
  font-family: system-ui, -apple-system, sans-serif;
}

4. ตั้งค่า Better Auth Client

สร้าง src/lib/auth-client.ts:

import { createAuthClient } from "better-auth/react";

export const authClient = createAuthClient({
  baseURL: "http://localhost:3000",
});

export const { signIn, signUp, useSession } = authClient;

5. สร้าง UI การยืนยันตัวตน

แทนที่ src/App.tsx ด้วยอินเทอร์เฟซการยืนยันตัวตนที่สมบูรณ์:

import { useState } from 'react';
import { useSession, signIn, signUp } from './lib/auth-client';

function App() {
  const { data: session, isPending } = useSession();
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [name, setName] = useState('');

  const handleSignUp = async (e: React.FormEvent) => {
    e.preventDefault();
    await signUp.email({
      name,
      email,
      password,
      callbackURL: '/',
    });
  };

  const handleSignIn = async (e: React.FormEvent) => {
    e.preventDefault();
    await signIn.email({
      email,
      password,
    });
  };

  const handleSignOut = async () => {
    await authClient.signOut();
  };

  if (isPending) return <div className="flex items-center justify-center min-h-screen">Loading...</div>;

  return (
    <div className="min-h-screen bg-gray-100 flex items-center justify-center p-4">
      <div className="max-w-md w-full bg-white rounded-lg shadow-md p-6">
        <h1 className="text-2xl font-bold text-center mb-6 text-gray-800">
          Better Auth API Test
        </h1>

        {session?.user ? (
          <div className="space-y-4">
            <div className="bg-green-50 p-4 rounded-md">
              <p className="text-green-800 font-semibold">Logged in as:</p>
              <p className="text-green-700">{session.user.email}</p>
              <p className="text-green-600 text-sm">{session.user.name}</p>
            </div>
            <button
              onClick={handleSignOut}
              className="w-full bg-red-500 hover:bg-red-600 text-white font-medium py-2 px-4 rounded-md transition"
            >
              Sign Out
            </button>
          </div>
        ) : (
          <div className="space-y-4">
            <form onSubmit={handleSignUp} className="space-y-3">
              <h2 className="text-lg font-semibold text-gray-700">Sign Up</h2>
              <input
                type="text"
                placeholder="Name"
                value={name}
                onChange={(e) => setName(e.target.value)}
                className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
                required
              />
              <input
                type="email"
                placeholder="Email"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
                className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
                required
              />
              <input
                type="password"
                placeholder="Password"
                value={password}
                onChange={(e) => setPassword(e.target.value)}
                className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
                required
              />
              <button
                type="submit"
                className="w-full bg-green-500 hover:bg-green-600 text-white font-medium py-2 px-4 rounded-md transition"
              >
                Create Account
              </button>
            </form>

            <form onSubmit={handleSignIn} className="space-y-3">
              <h2 className="text-lg font-semibold text-gray-700">Sign In</h2>
              <input
                type="email"
                placeholder="Email"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
                className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
                required
              />
              <input
                type="password"
                placeholder="Password"
                value={password}
                onChange={(e) => setPassword(e.target.value)}
                className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
                required
              />
              <button
                type="submit"
                className="w-full bg-blue-500 hover:bg-blue-600 text-white font-medium py-2 px-4 rounded-md transition"
              >
                Sign In
              </button>
            </form>
          </div>
        )}
      </div>
    </div>
  );
}

export default App;
โครงสร้างโปรเจกต์แอปส่วนหน้า

ขั้นตอนที่ 3: การทดสอบการผสานรวม

1. เริ่มเซิร์ฟเวอร์ส่วนหลัง

cd better-auth-backend
bun dev
เรียกใช้เซิร์ฟเวอร์ส่วนหลังของ Better Auth

2. เริ่มการพัฒนาส่วนหน้า

cd better-auth-frontend
bun dev
เรียกใช้แอปส่วนหน้าของ Better Auth

3. ทดสอบขั้นตอนการยืนยันตัวตน

ลงทะเบียนหรือเข้าสู่ระบบ
ข้อมูลที่ถูกต้อง
ความพยายามเข้าสู่ระบบด้วยข้อมูลที่ไม่ถูกต้อง
ข้อมูลไม่ถูกต้อง
ออกจากระบบ

ประโยชน์หลักของ Better Auth API

Better Auth API มีข้อดีที่น่าสนใจหลายประการที่ทำให้โดดเด่น:

คำถามที่พบบ่อย

คำถามที่ 1: ฉันสามารถใช้ Better Auth API กับ npm แทน Bun ได้หรือไม่?
คำตอบ: ได้อย่างแน่นอน แม้ว่าคู่มือนี้จะใช้ Bun เพื่อประโยชน์ด้านประสิทธิภาพ แต่ทุกคำสั่งก็มีคำสั่งที่เทียบเท่าใน npm แทนที่ bun add ด้วย npm install, bun dev ด้วย npm run dev และ bunx ด้วย npx โค้ดเฉพาะของ Bun เพียงอย่างเดียวคือการนำเข้า bun:sqlite ซึ่งสามารถแทนที่ด้วย better-sqlite3 สำหรับสภาพแวดล้อม Node.js

คำถามที่ 2: ทำไมเราถึงต้องใช้ Drizzle ORM? Better Auth ไม่สามารถสร้างตารางได้เองโดยอัตโนมัติหรือ?
คำตอบ: Better Auth ยึดหลักการจัดการฐานข้อมูลที่ชัดเจน Drizzle ให้การย้ายข้อมูลที่ปลอดภัยจากประเภทข้อมูล, การกำหนดเวอร์ชันสคีมา และป้องกันการสูญหายของข้อมูลโดยไม่ตั้งใจ คำสั่ง drizzle-kit push เป็นการตั้งค่าครั้งเดียวที่ให้คุณควบคุมการพัฒนาฐานข้อมูลของคุณได้อย่างเต็มที่

คำถามที่ 3: จะเกิดอะไรขึ้นหากฉันพบข้อผิดพลาด "Missing parameter name"?
คำตอบ: สิ่งนี้เกิดขึ้นเมื่อใช้ app.all() กับ wildcards ใน Express วิธีแก้ไขคือการใช้ app.use("/api/auth", toNodeHandler(auth)) แทน ตัวจัดการของ Better Auth จะจัดการเส้นทางย่อยทั้งหมดภายใน ดังนั้น Express จึงไม่จำเป็นต้องจับคู่ wildcard

คำถามที่ 4: ฉันจะเพิ่มผู้ให้บริการยืนยันตัวตนทางสังคมได้อย่างไร?
คำตอบ: เปิดใช้งานปลั๊กอิน OAuth ในการกำหนดค่า Better Auth ของคุณ ตัวอย่างเช่น การเพิ่ม GitHub:

import { betterAuth } from "better-auth";
import { github } from "better-auth/plugins";

export const auth = betterAuth({
  plugins: [
    github({
      clientId: process.env.GITHUB_CLIENT_ID,
      clientSecret: process.env.GITHUB_CLIENT_SECRET,
    })
  ]
});

คำถามที่ 5: Better Auth API พร้อมสำหรับการใช้งานจริงหรือไม่?
คำตอบ: ใช่ Better Auth ขับเคลื่อนการยืนยันตัวตนสำหรับผลิตภัณฑ์ SaaS หลายรายการที่มีผู้ใช้นับพัน เฟรมเวิร์กนี้ใช้การจัดการเซสชันที่ปลอดภัย, การป้องกัน CSRF และปฏิบัติตามแนวทางของ OWASP อย่างไรก็ตาม ควรตรวจสอบการนำไปใช้งานเฉพาะของคุณเสมอและอัปเดต dependencies ให้เป็นปัจจุบัน

สรุป

การสร้างระบบยืนยันตัวตนตั้งแต่เริ่มต้นไม่จำเป็นอีกต่อไปด้วยโซลูชันที่ทันสมัยอย่าง Better Auth API ในคู่มือนี้ เราได้สร้างระบบยืนยันตัวตนที่สมบูรณ์—ตั้งแต่สคีมาฐานข้อมูลไปจนถึงส่วนประกอบ UI—ในเวลาไม่กี่นาที! การรวมกันของความยืดหยุ่นของ Better Auth, ความปลอดภัยของประเภทข้อมูลของ Drizzle ORM และประสิทธิภาพของ Bun สร้างประสบการณ์นักพัฒนาที่สามารถปรับขนาดได้ตั้งแต่การสร้างต้นแบบไปจนถึงการใช้งานจริง

กระบวนการทีละขั้นตอนแสดงให้เห็นว่าการยืนยันตัวตน แม้จะมีความสำคัญ แต่ก็ไม่จำเป็นต้องซับซ้อน ด้วยการใช้ประโยชน์จากสถาปัตยกรรมปลั๊กอินของ Better Auth และการออกแบบที่ไม่ขึ้นกับเฟรมเวิร์ก คุณสามารถมุ่งเน้นไปที่การสร้างคุณสมบัติที่สำคัญสำหรับผู้ใช้ของคุณ แทนที่จะต้องต่อสู้กับการนำไปใช้งานด้านความปลอดภัย

ไม่ว่าคุณจะกำลังสร้างโปรเจกต์ส่วนตัวหรือแอปพลิเคชันระดับองค์กร Better Auth API มอบรากฐานสำหรับการยืนยันตัวตนที่ปลอดภัย ปรับขนาดได้ และปรับให้เข้ากับความต้องการของคุณ—ไม่ใช่ในทางกลับกัน

💡
ต้องการเครื่องมือทดสอบ API ที่ยอดเยี่ยมที่สร้าง เอกสาร API ที่สวยงาม หรือไม่?

ต้องการแพลตฟอร์มแบบ All-in-One ที่รวมเข้าด้วยกันสำหรับทีมพัฒนาของคุณเพื่อทำงานร่วมกันด้วย ประสิทธิภาพสูงสุด หรือไม่?

Apidog ตอบสนองทุกความต้องการของคุณ และ มาแทนที่ Postman ในราคาที่ย่อมเยากว่ามาก!
ปุ่ม

ฝึกการออกแบบ API แบบ Design-first ใน Apidog

ค้นพบวิธีที่ง่ายขึ้นในการสร้างและใช้ API