ถ้าคุณทำเว็บที่มีหน้า Dashboard, Profile หรือหน้าข้อมูลสำคัญ คุณคงไม่อยากให้ใครก็ได้เข้าถึงข้อมูลพวกนั้นได้ง่ายๆ เราต้องล็อกอินก่อนถึงจะเข้าได้!
ในบทความนี้ เราจะมาดูกันว่า Next.js + NextAuth.js ใช้ทำ Protected Route (หน้าที่ต้องล็อกอินก่อนเข้า) ได้ยังไง
🚀 ทำไมต้องป้องกันหน้าเว็บ?
✅ ป้องกันข้อมูลสำคัญ
- ถ้าเว็บมีข้อมูลผู้ใช้ ห้ามให้คนที่ไม่ได้ล็อกอินเข้าถึง
✅ เพิ่มความปลอดภัย
- ไม่เปิดช่องให้ Bot หรือ Hacker แอบเข้ามาดูข้อมูล
✅ UX ดีขึ้น
- ถ้าไม่ได้ล็อกอิน 👉 Redirect ไปหน้า Login
- ล็อกอินแล้ว 👉 เข้าใช้งานได้ปกติ
สรุป: ทำให้เว็บ ปลอดภัย + เป็นระเบียบ + ใช้งานง่าย
🔥 วิธีทำ Protected Route ใน Next.js
1️⃣ ติดตั้ง NextAuth.js
ถ้ายังไม่มี NextAuth.js ให้ติดตั้งก่อนnpm install next-auth
2️⃣ ตั้งค่า NextAuth.js
สร้างไฟล์ pages/api/auth/[...nextauth].jsimport NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";
export default NextAuth({
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
}),
],
secret: process.env.NEXTAUTH_SECRET,
});
💡 Tip: เราใช้ Google Login แต่คุณเปลี่ยนไปใช้ Auth0, GitHub, หรือ Email/Password ได้
3️⃣ ตั้งค่า ENV
สร้างไฟล์ .env.local แล้วใส่ค่าGOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
NEXTAUTH_SECRET=your-random-secret
NEXTAUTH_URL=http://localhost:3000
🛑 ป้องกันหน้าที่ต้องล็อกอิน
❌ วิธีที่ 1: เช็กใน Component
import { useSession, signIn } from "next-auth/react";export default function Dashboard() {
const { data: session, status } = useSession();
if (status === "loading") return <p>Loading...</p>;
if (!session) return <button onClick={() => signIn()}>Login to access</button>;
return <h1>Welcome to your Dashboard, {session.user.name}!</h1>;
}
🔹 อธิบายโค้ด:
- ถ้ากำลังโหลด ให้แสดง Loading
- ถ้าไม่ได้ล็อกอิน ให้แสดงปุ่ม Login
- ถ้าล็อกอินแล้ว แสดงข้อมูลได้ปกติ
🚀 วิธีที่ 2: Redirect ไปหน้า Login อัตโนมัติ
ใช้ getServerSideProps เช็กสิทธิ์ก่อนโหลดหน้าimport { getSession } from "next-auth/react";
export async function getServerSideProps(context) {
const session = await getSession(context);
if (!session) {
return {
redirect: {
destination: "/login",
permanent: false,
},
};
}
return {
props: { session },
};
}
export default function Dashboard({ session }) {
return <h1>Welcome, {session.user.name}!</h1>;
}
🔹 อธิบายโค้ด:
- ถ้า ไม่ได้ล็อกอิน 👉 Redirect ไป /login
- ถ้า ล็อกอินแล้ว 👉 ให้เข้า Dashboard ได้
✅ ข้อดี:
- ป้องกันตั้งแต่ฝั่งเซิร์ฟเวอร์
- SEO Friendly เพราะไม่ได้บล็อกการโหลดหน้า
🔒 วิธีที่ 3: สร้าง Middleware ป้องกันทุกหน้า
ใช้ middleware.ts เพื่อบังคับให้ล็อกอินทุกครั้งที่เข้า /dashboardสร้างไฟล์ middleware.ts
import { NextRequest, NextResponse } from "next/server";
export function middleware(req: NextRequest) {
const token = req.cookies.get("next-auth.session-token");
if (!token) {
return NextResponse.redirect(new URL("/login", req.url));
}
return NextResponse.next();
}
export const config = {
matcher: "/dashboard/:path*",
};
🔹 อธิบายโค้ด:
- ถ้าไม่มี Token 👉 Redirect ไป /login
- ถ้ามี Token 👉 อนุญาตให้เข้า /dashboard ได้
✅ ข้อดี:
- ป้องกันทุกหน้าใน /dashboard/ อัตโนมัติ
- ไม่ต้องใส่โค้ดป้องกันทุกไฟล์
🎨 สร้างหน้า Login
สร้าง pages/login.jsimport { signIn } from "next-auth/react";
export default function Login() {
return (
<div>
<h1>Login</h1>
<button onClick={() => signIn("google")}>Login with Google</button>
</div>
);
}
🔹 อธิบายโค้ด:
- ปุ่มเดียวจบ! กดแล้วล็อกอินผ่าน Google
❓ คำถามที่พบบ่อย
1️⃣ ควรใช้วิธีไหนดีที่สุด?
ขึ้นอยู่กับโปรเจ็กต์:- หน้าเดียวกัน (Client-side protection) 👉 useSession()
- ป้องกันทุกหน้า (Server-side protection) 👉 getServerSideProps()
- ป้องกันโฟลเดอร์ (Global protection) 👉 middleware.ts
2️⃣ NextAuth.js รองรับอะไรบ้าง?
- Google, Facebook, GitHub, Apple, Twitter
- Email/Password
- Magic Link
3️⃣ ถ้าอยากให้บางหน้าล็อกอิน แต่บางหน้าไม่ต้องทำไง?
- ใช้ Middleware เฉพาะโฟลเดอร์
- เช็ก useSession() ใน Component
🎉 สรุป
- ป้องกันหน้าเว็บที่ต้องล็อกอินก่อนเข้าใช้งาน ได้หลายวิธี
- ใช้ useSession() ถ้าต้องการป้องกันจากฝั่ง Client
- ใช้ getServerSideProps() ถ้าต้องการ Redirect อัตโนมัติ
- ใช้ middleware.ts ถ้าต้องการป้องกันทั้งโฟลเดอร์