การยืนยันตัวตนเป็นรากฐานสำคัญของเว็บแอปพลิเคชันสมัยใหม่ แต่การตั้งค่าก็ยังคงเป็นหนึ่งในความท้าทายที่ใช้เวลานานที่สุดที่นักพัฒนาต้องเผชิญ ขอแนะนำ Better Auth API—โซลูชันการยืนยันตัวตนที่ไม่ขึ้นกับเฟรมเวิร์ก ซึ่งสัญญาว่าจะเปลี่ยนแปลงวิธีการจัดการผู้ใช้ของเรา ในคู่มือฉบับสมบูรณ์นี้ เราจะพาคุณสร้างแอปพลิเคชันแบบฟูลสแต็กที่สมบูรณ์ ซึ่งแสดงให้เห็นถึงพลังและความเรียบง่ายของ Better Auth โดยใช้ Bun เพื่อประสิทธิภาพที่รวดเร็วเป็นพิเศษ
ต้องการแพลตฟอร์มแบบ 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: ข้อกำหนดเบื้องต้นและการตั้งค่าโปรเจกต์
ก่อนที่จะลงมือเขียนโค้ด ตรวจสอบให้แน่ใจว่าคุณได้ติดตั้งสิ่งต่อไปนี้แล้ว:
- Bun 1.0+: เราจะใช้ Bun ตลอดบทช่วยสอนนี้เพื่อความเร็วที่ยอดเยี่ยมและเครื่องมือที่ทันสมัย
- Node.js 18+: จำเป็นสำหรับรันไทม์ส่วนหลัง
- โปรแกรมแก้ไขโค้ด: แนะนำ VS Code สำหรับการรองรับ TypeScript

แม้ว่าการตั้งค่านี้จะทำงานได้อย่างสมบูรณ์แบบกับ 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

2. เริ่มการพัฒนาส่วนหน้า
cd better-auth-frontend
bun dev

3. ทดสอบขั้นตอนการยืนยันตัวตน
- เปิด
http://localhost:5173ในเบราว์เซอร์ของคุณ - ลงทะเบียนผู้ใช้ใหม่โดยใช้ฟอร์ม Sign-Up


- สังเกตไฟล์ฐานข้อมูลที่เพิ่มขนาดขึ้นเมื่อตารางถูกเติม
- ออกจากระบบและเข้าสู่ระบบอีกครั้งเพื่อตรวจสอบการจัดการเซสชัน
- ตรวจสอบเอนด์พอยต์เซสชัน:
http://localhost:3000/api/auth/session

ประโยชน์หลักของ Better Auth API
Better Auth API มีข้อดีที่น่าสนใจหลายประการที่ทำให้โดดเด่น:
- ไม่ขึ้นกับเฟรมเวิร์ก (Framework Agnosticism): ไม่เหมือนกับ NextAuth.js หรือ Firebase Auth, Better Auth ทำงานได้ทุกที่ที่ JavaScript ทำงาน ตรรกะการยืนยันตัวตนเดียวกันนี้สามารถใช้ได้กับไคลเอ็นต์เว็บ, มือถือ และ API โดยไม่ต้องแก้ไข
- กลยุทธ์การยืนยันตัวตนที่หลากหลาย: รองรับการยืนยันตัวตนด้วยข้อมูลประจำตัว, OAuth 2.0, passkeys, การยืนยันตัวตนแบบสองขั้นตอน และ magic links แต่ละกลยุทธ์เป็นปลั๊กอินที่สามารถเปิดใช้งานได้ด้วยการกำหนดค่าเพียงบรรทัดเดียว
- ความปลอดภัยของประเภทข้อมูล (Type Safety): การรองรับ TypeScript อย่างเต็มรูปแบบพร้อมประเภทข้อมูลที่อนุมานจากสคีมาฐานข้อมูลของคุณ ช่วยขจัดปัญหา "any" type ที่พบบ่อยในโค้ดเบสการยืนยันตัวตน
- ความยืดหยุ่นของฐานข้อมูล (Database Flexibility): อะแดปเตอร์ Drizzle ORM หมายความว่าคุณสามารถสลับระหว่าง SQLite, PostgreSQL และ MySQL โดยไม่ต้องเปลี่ยนตรรกะการยืนยันตัวตนของคุณ บทช่วยสอนนี้ใช้ SQLite เพื่อความเรียบง่าย แต่โค้ดเดียวกันนี้สามารถปรับขนาดไปยังฐานข้อมูลที่ใช้งานจริงได้
- ระบบนิเวศปลั๊กอิน (Plugin Ecosystem): ต้องการการรองรับองค์กรหรือไม่? Multi-tenancy? บทบาทผู้ดูแลระบบ? ระบบปลั๊กอินของ Better Auth ช่วยให้คุณขยายฟังก์ชันการทำงานได้โดยไม่ทำให้ส่วนหลักมีขนาดใหญ่เกินไป
- ประสิทธิภาพ: ด้วย Bun เป็นรันไทม์ การเริ่มทำงานแบบ cold start ใช้เวลาน้อยกว่า 100 มิลลิวินาที และขั้นตอนการยืนยันตัวตนทั้งหมดเสร็จสมบูรณ์ในเวลาน้อยกว่า 50 มิลลิวินาทีบนฮาร์ดแวร์ทั่วไป
คำถามที่พบบ่อย
คำถามที่ 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 มอบรากฐานสำหรับการยืนยันตัวตนที่ปลอดภัย ปรับขนาดได้ และปรับให้เข้ากับความต้องการของคุณ—ไม่ใช่ในทางกลับกัน
ต้องการแพลตฟอร์มแบบ All-in-One ที่รวมเข้าด้วยกันสำหรับทีมพัฒนาของคุณเพื่อทำงานร่วมกันด้วย ประสิทธิภาพสูงสุด หรือไม่?
Apidog ตอบสนองทุกความต้องการของคุณ และ มาแทนที่ Postman ในราคาที่ย่อมเยากว่ามาก!
