Đăng nhập

📘 BÀI 24: PHÂN QUYỀN NGƯỜI DÙNG (ROLE-BASED AUTHENTICATION)

Phân quyền người dùng – Admin và Người dùng thường, bạn sẽ học cách tạo hệ thống quản lý quyền truy cập. Điều này rất quan trọng khi ứng dụng của bạn có nhiều loại người dùng khác nhau, ví dụ:

  • Admin có thể xem và quản lý toàn bộ todo
  • Người dùng chỉ được xem và chỉnh sửa todo của riêng họ

Mục tiêu

  • Gán role khi đăng ký (mặc định là user)
  • Bảo vệ route theo role
  • Giao diện Vue hiển thị theo quyền hạn
  • Tách logic giữa admin và người dùng thường

Phần 1: Thêm role cho User model

Trong models/User.js, cập nhật schema:

const userSchema = new mongoose.Schema({
  username: { type: String, unique: true },
  password: String,
  role: { type: String, default: 'user' } // 'user' hoặc 'admin'
})

Bạn có thể tự tạo một user admin thủ công bằng MongoDB CLI hoặc script seed:

new User({ username: 'admin', password: '123456', role: 'admin' }).save()

Phần 2: Cập nhật JWT để gửi thêm role

Trong API /auth/login, sau khi xác thực:

const token = jwt.sign(
  { userId: user._id, role: user.role },
  SECRET,
  { expiresIn: '7d' }
)

Khi verify trong middleware:

function authMiddleware(req, res, next) {
  const token = req.headers.authorization?.split(' ')[1]
  if (!token) return res.status(401).json({ error: 'Unauthorized' })
  try {
    const decoded = jwt.verify(token, SECRET)
    req.userId = decoded.userId
    req.userRole = decoded.role
    next()
  } catch (e) {
    return res.status(403).json({ error: 'Invalid token' })
  }
}

Phần 3: Tạo middleware kiểm tra quyền admin

function adminOnly(req, res, next) {
  if (req.userRole !== 'admin') {
    return res.status(403).json({ error: 'Access denied' })
  }
  next()
}

Ví dụ: chỉ admin mới được lấy toàn bộ todo từ tất cả người dùng

app.get('/admin/todos', authMiddleware, adminOnly, async (req, res) => {
  const allTodos = await Todo.find().sort({ createdAt: -1 })
  res.json(allTodos)
})

Phần 4: Vue hiển thị tùy theo role

Trong authStore.js, bạn có thể lưu role sau khi login:

if (res.ok) {
  const token = data.token
  const decoded = JSON.parse(atob(token.split('.')[1]))
  this.token = token
  this.role = decoded.role
  localStorage.setItem('token', token)
}

Thêm vào state:

role: '', // 'user' hoặc 'admin'

Trong giao diện Vue:

<template>
  <div>
    <h2>Todo của bạn</h2>
    <!-- hiện thêm link quản trị nếu là admin -->
    <router-link v-if="auth.role === 'admin'" to="/admin">Quản trị</router-link>
  </div>
</template>

<script setup>
import { useAuthStore } from '@/store/authStore'
const auth = useAuthStore()
</script>

Phần 5: Tạo trang quản trị Todo (Admin)

Tạo AdminTodos.vue để gọi API /admin/todos và hiển thị toàn bộ todo từ tất cả người dùng.

Bạn có thể mở rộng:

  • Lọc theo user
  • Xoá todo bất kỳ
  • Gắn thêm thông tin người tạo todo

Bạn đã học được

  • Thêm role cho người dùng (user / admin)
  • Phân quyền route API backend
  • Kiểm tra và hiển thị chức năng tùy theo quyền trong Vue
  • Cấu trúc ứng dụng có khả năng mở rộng về phân quyền

Bài tập mở rộng

  1. Thêm màn hình quản lý người dùng cho admin (danh sách, xóa, cấp quyền)
  2. Cho phép nâng cấp role từ user → admin thông qua bảng quản trị
  3. Triển khai một hệ thống permission chi tiết hơn (theo action: create, edit, delete)

Thảo luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Đăng ký nhận tin mới

Nhận bài học, tài nguyên và cơ hội việc làm qua email hàng tuần.

Chúng tôi cam kết không spam. Bạn có thể hủy bất cứ lúc nào.