วันเสาร์ที่ 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 ที่ช่วยให้รูปภาพโหลดเร็วขึ้น อัตโนมัติ ไม...