แสดงบทความที่มีป้ายกำกับ Protected Route แสดงบทความทั้งหมด
แสดงบทความที่มีป้ายกำกับ Protected Route แสดงบทความทั้งหมด

วันอังคารที่ 25 มีนาคม พ.ศ. 2568

วิธีป้องกันหน้าเว็บที่ต้องล็อกอินก่อนเข้าใช้งานใน Next.js

อย่าปล่อยให้ใครเข้ามาเที่ยวเว็บเราฟรีๆ! 😆

ถ้าคุณทำเว็บที่มีหน้า 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].js

import 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.js

import { 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 ถ้าต้องการป้องกันทั้งโฟลเดอร์
ลองทำดู แล้วจะติดใจ! 😉

การใช้ Image Optimization ใน Next.js: โหลดไว SEO ดี ประหยัดแบนด์วิธ!

เคยเจอปัญหาเว็บโหลดช้าเพราะรูปภาพขนาดใหญ่หรือเปล่า? 📷 ถ้าใช่ Next.js มีฟีเจอร์ Image Optimization ที่ช่วยให้รูปภาพโหลดเร็วขึ้น อัตโนมัติ ไม...