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

วันจันทร์ที่ 24 มีนาคม พ.ศ. 2568

วิธีใช้ Auth0 กับ Next.js แบบเข้าใจง่าย

ถ้าขี้เกียจทำระบบล็อกอินเอง ให้ Auth0 จัดการให้เถอะ!

Auth0 เป็นแพลตฟอร์มจัดการการยืนยันตัวตน (Authentication) ที่ช่วยให้เราทำระบบล็อกอินได้เร็วขึ้น โดยไม่ต้องมานั่งเขียนโค้ดยาวๆ ทำให้เว็บปลอดภัยขึ้นแบบไม่ต้องปวดหัว

ในบทความนี้ เราจะมาใช้ Auth0 กับ Next.js เพื่อทำระบบล็อกอินที่รองรับ OAuth (Google, Facebook ฯลฯ) และ Email/Password ได้ง่ายๆ


🚀 ทำไมต้องใช้ Auth0?

✅ ลดเวลาพัฒนา

  •     ไม่ต้องสร้างระบบยืนยันตัวตนเอง
  •     มี UI สำเร็จรูปให้ใช้เลย

✅ รองรับหลายวิธี

  •     ล็อกอินด้วย Google, Facebook, Apple, GitHub ฯลฯ
  •     ใช้ Magic Link หรือ OTP ก็ได้
  •     ใช้ Username/Password แบบปกติก็ได้

✅ ปลอดภัยกว่า

  •     มีการเข้ารหัสและป้องกันแฮก
  •     รองรับ MFA (Multi-Factor Authentication)


สรุปง่ายๆ Auth0 = เร็ว + ปลอดภัย + ใช้งานง่าย


🎯 มาเริ่มกันเลย!

1️⃣ สร้างโปรเจ็กต์ Next.js

ถ้ายังไม่มีโปรเจ็กต์ Next.js ให้สร้างก่อน

npx create-next-app@latest auth0-demo
cd auth0-demo
npm install

2️⃣ สมัครและตั้งค่า Auth0

  1.     ไปที่ Auth0 Dashboard แล้วสมัครบัญชี
  2.     สร้าง Application ใหม่
    • เลือก Single Page Application
    • ใส่ Callback URL: http://localhost:3000/api/auth/callback/auth0
    • ใส่ Logout URL: http://localhost:3000/
  3. คัดลอก Client ID และ Client Secret


3️⃣ ติดตั้ง NextAuth.js (ใช้ Auth0 เป็น Provider)

ติดตั้งแพ็กเกจที่ต้องใช้

npm install next-auth @auth0/nextjs-auth0

4️⃣ ตั้งค่า NextAuth.js

สร้างไฟล์ pages/api/auth/[...nextauth].js

import NextAuth from "next-auth";
import Auth0Provider from "next-auth/providers/auth0";

export default NextAuth({
  providers: [
    Auth0Provider({
      clientId: process.env.AUTH0_CLIENT_ID,
      clientSecret: process.env.AUTH0_CLIENT_SECRET,
      issuer: process.env.AUTH0_ISSUER,
    }),
  ],
  secret: process.env.NEXTAUTH_SECRET,
});

5️⃣ ตั้งค่า ENV

สร้างไฟล์ .env.local แล้วใส่ค่าเหล่านี้

AUTH0_CLIENT_ID=your-client-id
AUTH0_CLIENT_SECRET=your-client-secret
AUTH0_ISSUER=https://your-auth0-domain/
NEXTAUTH_SECRET=your-random-secret
NEXTAUTH_URL=http://localhost:3000

💡 Tip: ค่า NEXTAUTH_SECRET ใช้คำสั่งนี้สร้างแบบสุ่มได้

openssl rand -base64 32

6️⃣ สร้างปุ่ม Login / Logout

สร้างไฟล์ pages/index.js

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

export default function Home() {
  const { data: session } = useSession();

  return (
    <div>
      <h1>Next.js + Auth0</h1>
      {session ? (
        <>
          <p>Welcome, {session.user.name}!</p>
          <button onClick={() => signOut()}>Logout</button>
        </>
      ) : (
        <button onClick={() => signIn("auth0")}>Login with Auth0</button>
      )}
    </div>
  );
}

🔹 อธิบายโค้ด:

  •     ใช้ useSession() เช็กว่าผู้ใช้ล็อกอินหรือยัง
  •     ถ้าล็อกอินแล้ว แสดงชื่อ + ปุ่ม Logout
  •     ถ้ายังไม่ล็อกอิน แสดงปุ่ม Login


🔥 ทดสอบใช้งาน

  1.     รันเซิร์ฟเวอร์ npm run dev
  2.     เข้าไปที่หน้าเว็บ http://localhost:3000
  3.     กดปุ่ม "Login with Auth0"
  4.     ล็อกอินผ่าน Google หรือ Email/Password
  5.     ถ้าสำเร็จจะกลับมาหน้าเว็บและแสดงชื่อ! 🎉


🎨 ทำหน้า Profile

สร้างไฟล์ pages/profile.js

import { useUser } from "@auth0/nextjs-auth0/client";

export default function Profile() {
  const { user, error, isLoading } = useUser();

  if (isLoading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    user && (
      <div>
        <h1>{user.name}</h1>
        <p>Email: {user.email}</p>
        <img src={user.picture} alt={user.name} width={100} />
      </div>
    )
  );
}

🔹 อธิบายโค้ด:

  •     ใช้ useUser() ดึงข้อมูลผู้ใช้จาก Auth0
  •     แสดง ชื่อ, อีเมล, รูปโปรไฟล์


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

1️⃣ Auth0 ใช้ฟรีไหม?

ใช่! แต่แผนฟรีจำกัด 7,000 ล็อกอินต่อเดือน ถ้าใช้เยอะกว่านี้ต้องอัปเกรด

2️⃣ รองรับ Social Login อะไรบ้าง?

Google, Facebook, Apple, GitHub, Twitter ฯลฯ

3️⃣ ถ้าอยากใช้ Magic Link ต้องทำไง?

Auth0 รองรับ Passwordless Login (Magic Link, OTP) แค่เปิดใช้งานใน Dashboard


🎉 สรุป

  •     Auth0 ช่วยให้ทำระบบล็อกอินได้เร็วขึ้น
  •     ใช้ NextAuth.js เชื่อม Auth0 กับ Next.js
  •     รองรับ Social Login, Email/Password, Magic Link
  •     ปลอดภัย ไม่ต้องจัดการรหัสผ่านเอง

ลองทำดู แล้วจะติดใจ! 😉

วันเสาร์ที่ 15 มีนาคม พ.ศ. 2568

การจัดการ Authentication กับฐานข้อมูล ใน Next.js

การสร้างระบบ Authentication หรือการยืนยันตัวตนในแอปพลิเคชันเว็บคือขั้นตอนที่สำคัญที่สุดขั้นตอนหนึ่งในการพัฒนาเว็บแอป เพราะไม่ว่าระบบนั้นจะเป็นระบบที่ให้ผู้ใช้ทำการสมัครสมาชิก เข้าสู่ระบบ หรือแม้แต่การเข้าถึงข้อมูลส่วนตัว การมีระบบที่สามารถจัดการ Authentication ได้ดีจะช่วยให้การใช้งานระบบมีความปลอดภัย และมั่นใจได้ว่า ผู้ใช้ที่เข้ามาจะต้องมีสิทธิ์ ในการใช้งานตามที่กำหนด

สำหรับ Next.js ซึ่งเป็น framework ที่พัฒนาโดย React, การจัดการ Authentication ถือเป็นส่วนที่สำคัญ โดยเฉพาะอย่างยิ่งเมื่อเราต้องทำการจัดการกับฐานข้อมูล เช่น MySQL, MongoDB หรือ PostgreSQL ซึ่งในบทความนี้เราจะพูดถึงวิธีการจัดการ Authentication บน Next.js ด้วยการเชื่อมต่อกับฐานข้อมูล โดยใช้เครื่องมือที่นิยมอย่าง bcrypt และ JWT (JSON Web Token) เพื่อให้ผู้ใช้สามารถลงทะเบียน เข้าสู่ระบบ และสามารถเข้าถึงข้อมูลที่มีการรักษาความปลอดภัยได้

เริ่มต้นสร้างโปรเจคใน Next.js

ก่อนที่เราจะเริ่มต้นการสร้างระบบ Authentication ด้วย Next.js เราต้องสร้างโปรเจค Next.js ขึ้นมาก่อน และติดตั้งแพ็กเกจที่จำเป็นบางตัว ซึ่งในที่นี้เราจะใช้ bcryptjs สำหรับการเข้ารหัสรหัสผ่าน, jsonwebtoken (JWT) สำหรับการสร้างและจัดการ Token, และ Prisma หรือ Sequelize สำหรับการจัดการกับฐานข้อมูล

1. สร้างโปรเจค Next.js

การสร้างโปรเจค Next.js เป็นขั้นตอนที่ง่ายมาก เพียงแค่ใช้คำสั่งต่อไปนี้ในเทอร์มินัล:

npx create-next-app@latest my-auth-app
cd my-auth-app

เมื่อสร้างโปรเจคเสร็จแล้ว ให้ทำการติดตั้ง dependencies ที่จำเป็น:

npm install bcryptjs jsonwebtoken prisma @prisma/client

2. ตั้งค่า Prisma สำหรับฐานข้อมูล


ถ้าคุณเลือกใช้ Prisma ในการจัดการฐานข้อมูลคุณต้องทำการตั้งค่า Prisma เพื่อเชื่อมต่อกับฐานข้อมูลที่คุณใช้ เช่น MySQL, PostgreSQL, หรือ SQLite ต่อไปนี้คือการตั้งค่าพื้นฐานสำหรับ Prisma:
  • สร้างไฟล์ schema.prisma ที่อยู่ในโฟลเดอร์ prisma สำหรับกำหนดโครงสร้างของฐานข้อมูล

npx prisma init


  • จากนั้นแก้ไขไฟล์ schema.prisma เพื่อกำหนด Model สำหรับผู้ใช้:

model User {
  id        Int    @id @default(autoincrement())
  email     String @unique
  password  String
  createdAt DateTime @default(now())
}


  • หลังจากที่ตั้งค่าฐานข้อมูลเสร็จแล้ว ให้ทำการ Migrate โครงสร้างฐานข้อมูล:
npx prisma migrate dev --name init

ตอนนี้คุณก็พร้อมที่จะใช้ Prisma ในการติดต่อกับฐานข้อมูลแล้ว

การลงทะเบียนผู้ใช้ (Registration)

ในการสร้างระบบการลงทะเบียนเราต้องให้ผู้ใช้กรอกข้อมูล เช่น อีเมล และ รหัสผ่าน โดยระบบจะทำการเข้ารหัสรหัสผ่านก่อนเก็บลงในฐานข้อมูล เพื่อให้ปลอดภัยจากการโจมตีต่างๆ โดยการใช้ bcryptjs ในการเข้ารหัสรหัสผ่านก่อนเก็บ

ตัวอย่างการลงทะเบียนผู้ใช้ใน Next.js API route

// pages/api/auth/register.js
import bcrypt from 'bcryptjs';
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { email, password } = req.body;

    // ตรวจสอบว่าอีเมลมีอยู่ในฐานข้อมูลหรือไม่
    const existingUser = await prisma.user.findUnique({
      where: { email },
    });

    if (existingUser) {
      return res.status(400).json({ message: 'User already exists' });
    }

    // เข้ารหัสรหัสผ่านก่อนเก็บ
    const hashedPassword = await bcrypt.hash(password, 12);

    // สร้างผู้ใช้ใหม่ในฐานข้อมูล
    const newUser = await prisma.user.create({
      data: {
        email,
        password: hashedPassword,
      },
    });

    return res.status(201).json(newUser);
  } else {
    res.status(405).json({ message: 'Method not allowed' });
  }
}

ในโค้ดนี้เราทำการตรวจสอบว่าอีเมลของผู้ใช้ที่กรอกมีอยู่ในฐานข้อมูลหรือไม่ ถ้ามีระบบจะแจ้งว่าผู้ใช้นั้นมีอยู่แล้ว แต่ถ้าไม่มีก็จะทำการเข้ารหัสรหัสผ่านและสร้างผู้ใช้ใหม่ในฐานข้อมูล

การล็อกอินผู้ใช้ (Login)

เมื่อผู้ใช้ทำการล็อกอิน เราต้องตรวจสอบว่าอีเมลและรหัสผ่านที่กรอกเข้ามาถูกต้องหรือไม่ โดยการเปรียบเทียบรหัสผ่านที่กรอกกับรหัสผ่านที่ถูกเข้ารหัสไว้ในฐานข้อมูล จากนั้น ถ้าถูกต้อง เราจะสร้าง JWT (JSON Web Token) เพื่อใช้ในการยืนยันตัวตนของผู้ใช้ในคำขอต่อไป

ตัวอย่างการล็อกอินใน Next.js API route

// pages/api/auth/login.js
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export default async function handler(req, res) {
  if (req.method === 'POST') {
    const { email, password } = req.body;

    // ค้นหาผู้ใช้ในฐานข้อมูล
    const user = await prisma.user.findUnique({
      where: { email },
    });

    if (!user) {
      return res.status(400).json({ message: 'User not found' });
    }

    // เปรียบเทียบรหัสผ่าน
    const isPasswordValid = await bcrypt.compare(password, user.password);
    if (!isPasswordValid) {
      return res.status(400).json({ message: 'Invalid password' });
    }

    // สร้าง JWT Token
    const token = jwt.sign({ userId: user.id }, 'your_jwt_secret', {
      expiresIn: '1h',
    });

    return res.status(200).json({ token });
  } else {
    res.status(405).json({ message: 'Method not allowed' });
  }
}

ในโค้ดนี้:

  1. ระบบจะค้นหาผู้ใช้จาก อีเมล ที่ผู้ใช้กรอก
  2. ถ้าพบผู้ใช้, ระบบจะทำการเปรียบเทียบ รหัสผ่านที่กรอก กับ รหัสผ่านที่เข้ารหัส ในฐานข้อมูล
  3. ถ้ารหัสผ่านถูกต้อง, ระบบจะสร้าง JWT Token และส่งกลับไปให้ผู้ใช้


การใช้งาน Token ในการยืนยันตัวตน

หลังจากที่ผู้ใช้ล็อกอินสำเร็จและได้รับ JWT Token, ผู้ใช้จะต้องส่ง Token นี้กลับมาในคำขอถัดไป เพื่อให้ระบบสามารถยืนยันตัวตนของผู้ใช้ได้

ตัวอย่างการป้องกัน API ด้วย JWT

// pages/api/protected.js
import jwt from 'jsonwebtoken';

export default function handler(req, res) {
  const token = req.headers['authorization']?.split(' ')[1];

  if (!token) {
    return res.status(401).json({ message: 'No token provided' });
  }

  try {
    const decoded = jwt.verify(token, 'your_jwt_secret');
    res.status(200).json({ message: 'This is a protected route', userId: decoded.userId });
  } catch (error) {
    res.status(401).json({ message: 'Invalid or expired token' });
  }
}

ในตัวอย่างนี้, ระบบจะตรวจสอบว่า JWT Token ที่ส่งมาพร้อมกับคำขอเป็น Token ที่ถูกต้อง หรือไม่ ถ้าถูกต้อง ระบบจะอนุญาตให้เข้าถึงข้อมูลที่ต้องการได้

สรุป

การจัดการ Authentication ใน Next.js เป็นกระบวนการที่ไม่ซับซ้อนและสามารถทำได้อย่างมีประสิทธิภาพ โดยใช้เครื่องมือที่ได้รับความนิยม เช่น bcryptjs สำหรับการเข้ารหัสรหัสผ่าน และ JWT สำหรับการสร้างและตรวจสอบ Token ซึ่งช่วยให้ระบบของเรามีความปลอดภัยและยืดหยุ่น

การใช้ Prisma ในการเชื่อมต่อฐานข้อมูลก็ทำให้การจัดการข้อมูลผู้ใช้มีความสะดวกและสามารถขยายได้ตามต้องการ โดยทั้งหมดนี้จะทำให้การสร้างระบบ Authentication ใน Next.js เป็นไปอย่างราบรื่นและปลอดภัย

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

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