0

[Series Thực Chiến E-commerce] Bài 9: Lên đồ cho Admin - Lấy danh sách toàn bộ người dùng

Chào anh em! (Link bài 8)

Vậy là chúng ta đã xử lý hòm hòm các tính năng cơ bản dành cho khách hàng (Đăng ký, Đăng nhập, Quên mật khẩu). Hôm nay, chúng ta sẽ bắt đầu xắn tay áo làm việc với "phần chìm của tảng băng": Hệ thống Quản trị (Admin Panel).

Việc đầu tiên mà một ông Admin (Quản trị viên) muốn làm khi đăng nhập vào hệ thống chắc chắn là xem danh sách khách hàng đang có trong hệ thống. Viết API lấy toàn bộ người dùng bằng Mongoose thì siêu dễ, anh em cùng xem nhé!

1. Viết API Query danh sách User (Controller)

Nhìn vào yêu cầu, logic cơ bản cực kỳ đơn giản: chúng ta chỉ cần dùng hàm find() của Mongoose để lôi toàn bộ data từ collection User lên là xong.

Anh em mở file controllers/user.js và thêm đoạn code này vào:

const asyncHandler = require('express-async-handler');
const User = require('../models/user'); // Đảm bảo anh em đã import đúng model từ các bài trước nhé

// Lấy danh sách toàn bộ người dùng
const getUsers = asyncHandler(async (req, res) => {
  // Lấy hết không chừa một ai
  const response = await User.find();

  return res.status(200).json({
    success: response ? true : false,
    users: response,
  });
});

module.exports = {
  getUsers,
  // ... các controller cũ như login, register, logout giữ nguyên nhé
};

2. Định tuyến API (Router)

Tiếp theo, mình lôi cái hàm getUsers này ra ngoài Router để Frontend có chỗ mà gọi.

Theo chuẩn thiết kế RESTful API, để lấy danh sách toàn bộ tài nguyên của một đối tượng (ở đây là User), mình sẽ dùng phương thức GET và trỏ thẳng vào root endpoint của đối tượng đó (tức là /).

Anh em mở file routers/user.js:

const express = require('express');
const router = express.Router();
const ctrls = require('../controllers/user');

// ... các route auth cũ (register, login, logout...)

// Route lấy toàn bộ người dùng (GET /api/user/)
router.get('/', ctrls.getUsers);

module.exports = router;

3. API chạy ngon, nhưng có "Biến" lớn!

Ok, code xong rồi. Anh em mở Postman lên, tạo một request GET bắn thẳng vào http://localhost:5000/api/user/ và BÙM! Một danh sách User trả về đầy đủ, mượt mà.

Nhưng anh em dừng lại một nhịp và nhìn kỹ vào cục JSON trả về trên Postman xem. Có thấy mùi "nguy hiểm" không?

Nếu anh em bê nguyên API này lên Production lúc này, dự án sẽ gặp 2 lỗ hổng bảo mật chết người:

  1. Lộ sạch dữ liệu nhạy cảm: Hàm User.find() ở trên đang bốc toàn bộ dữ liệu trong database ra, bao gồm cả password (dù đã băm) và refreshToken. Lộ cái này ra ngoài cho Frontend thì rủi ro bị hacker nhòm ngó là cực kỳ cao.

  2. Ai vào cũng được (No Authentication): Hiện tại, API này đang mở toang cửa. Bất kỳ ai (kể cả một thằng ất ơ không cần đăng nhập) chỉ cần biết đường link API là có thể chui vào xem được toàn bộ danh sách khách hàng của hệ thống! Lộ thông tin số điện thoại, email khách hàng cho đối thủ cạnh tranh thì... toang thật sự.

Lời kết

Mình cố tình viết API này ở dạng "thô" nhất để anh em thấy rõ vấn đề. Làm Backend không chỉ là gọi data ra cho chạy là xong, mà còn phải biết "che chắn" dữ liệu.

Để giải quyết triệt để 2 cái hố bom này, chúng ta cần:

  • Dùng kỹ thuật lọc dữ liệu (ẩn password, token đi).

  • Dựng chốt chặn: Chặn thằng chưa đăng nhập, và chặn luôn cả thằng đã đăng nhập nhưng chỉ là "User quèn" (không phải Admin).

Và đó chính xác là nội dung của bài tiếp theo: Lession 10: Permission Role Admin. Chuẩn bị sẵn logic cho phần phân quyền và ẩn data nhé anh em!


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí