Skip to content
Grok

Better Auth สำหรับ Next.js

Better Auth เป็นไลบรารีที่ช่วยให้การจัดการ Authentication ใน Next.js ง่ายขึ้น โดยรองรับทั้ง Email/Password, OAuth, และ Web3

การติดตั้ง

ติดตั้งแพ็คเกจที่จำเป็น:

bash
bun add better-auth @better-auth/nextjs
bash
npm install better-auth @better-auth/nextjs
bash
pnpm add better-auth @better-auth/nextjs
bash
yarn add better-auth @better-auth/nextjs

การตั้งค่า

1. ตั้งค่า Environment Variables

สร้างไฟล์ .env.local และเพิ่มค่าต่อไปนี้:

bash
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-secret-key
# ตั้งค่า providers ตามที่ต้องการ
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret

2. สร้าง Auth Configuration

สร้างไฟล์ app/api/auth/[...nextauth]/route.ts:

ts
import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";

export const authOptions = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
    // เพิ่ม providers อื่นๆ ตามต้องการ
  ],
  callbacks: {
    async session({ session, token }: { session: any; token: any }) {
      // เพิ่มข้อมูลเพิ่มเติมใน session
      session.user.id = token.sub;
      return session;
    },
  },
  secret: process.env.NEXTAUTH_SECRET,
};

const handler = NextAuth(authOptions);

export { handler as GET, handler as POST };

วิธีการใช้งาน

1. ตั้งค่า Provider

แก้ไขไฟล์ app/layout.tsx:

tsx
import { auth } from "@/auth";
import { SessionProvider } from "next-auth/react";

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const session = await auth();

  return (
    <html lang="th">
      <body>
        <SessionProvider session={session}>
          {children}
        </SessionProvider>
      </body>
    </html>
  );
}

2. หน้า Login

สร้างไฟล์ app/login/page.tsx:

tsx
"use client";

import { signIn } from "next-auth/react";
import { useRouter } from "next/navigation";

export default function LoginPage() {
  const router = useRouter();

  const handleGoogleSignIn = async () => {
    await signIn("google", { callbackUrl: "/dashboard" });
  };

  return (
    <div className="min-h-screen flex items-center justify-center bg-gray-50">
      <div className="max-w-md w-full space-y-8 p-8 bg-white rounded-lg shadow-md">
        <h2 className="text-2xl font-bold text-center">เข้าสู่ระบบ</h2>
        <button
          onClick={handleGoogleSignIn}
          className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500"
        >
          เข้าสู่ระบบด้วย Google
        </button>
      </div>
    </div>
  );
}

3. หน้า Dashboard

สร้างไฟล์ app/dashboard/page.tsx:

tsx
"use client";

import { signOut, useSession } from "next-auth/react";
import { useRouter } from "next/navigation";

export default function DashboardPage() {
  const { data: session, status } = useSession();
  const router = useRouter();

  if (status === "loading") {
    return <div>กำลังโหลด...</div>;
  }

  if (!session) {
    router.push("/login");
    return null;
  }

  const handleSignOut = async () => {
    await signOut({ callbackUrl: "/login" });
  };

  return (
    <div className="min-h-screen bg-gray-50 p-8">
      <div className="max-w-4xl mx-auto bg-white rounded-lg shadow p-6">
        <div className="flex justify-between items-center mb-8">
          <h1 className="text-2xl font-bold">แดชบอร์ด</h1>
          <button
            onClick={handleSignOut}
            className="px-4 py-2 bg-red-500 hover:bg-red-600 text-white rounded-md"
          >
            ออกจากระบบ
          </button>
        </div>

        <div className="space-y-4">
          <div className="p-4 bg-gray-50 rounded-lg">
            <h2 className="text-lg font-semibold mb-2">ข้อมูลผู้ใช้</h2>
            <p>
              <span className="font-medium">ชื่อ:</span> {session.user?.name}
            </p>
            <p>
              <span className="font-medium">อีเมล:</span> {session.user?.email}
            </p>
            {session.user?.image && (
              <img
                src={session.user.image}
                alt="Profile"
                className="w-20 h-20 rounded-full mt-4"
              />
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

การใช้งานกับ API Routes

1. สร้าง Protected API Route

สร้างไฟล์ app/api/protected/route.ts:

ts
import { authOptions } from "@/app/api/auth/[...nextauth]/route";
import { getServerSession } from "next-auth";
import { NextResponse } from "next/server";

export async function GET() {
  const session = await getServerSession(authOptions);

  if (!session) {
    return NextResponse.json(
      { error: "Unauthorized" },
      { status: 401 },
    );
  }

  return NextResponse.json({
    message: "ข้อมูลลับ",
    user: session.user,
  });
}

ข้อดีของ Better Auth

  1. รองรับหลาย Provider - ใช้งานได้กับ Google, Facebook, GitHub และอื่นๆ
  2. Type Safety - มี TypeScript support เต็มรูปแบบ
  3. Server Components - ทำงานได้ดีกับ Next.js 13+ App Router
  4. Customizable - ปรับแต่งได้ตามความต้องการ
  5. Secure - ใช้มาตรฐานความปลอดภัยระดับสูง

ข้อควรระวัง

  1. อย่าลืมตั้งค่า NEXTAUTH_SECRET ให้ปลอดภัย
  2. ใช้ HTTPS ใน production
  3. ตั้งค่า CORS ให้ถูกต้อง
  4. ตรวจสอบสิทธิ์การเข้าถึงในทุก API Route

แหล่งข้อมูลเพิ่มเติม