Thiết Kế và Xây Dựng Hệ Thống Mạng Xã hội Trực tuyến với Spring Boot và Vue.js

Tổng Quan Về Hệ Thống

Việc phát triển các nền tảng mạng xã hội hiện đại đòi hỏi một kiến trúc mạnh mẽ, khả năng mở rộng cao và trải nghiệm người dùng mượt mà. Bài viết này trình bày quy trình thiết kế và triển khai một hệ thống mạng xã hội dựa trên sự kết hợp giữa Spring Boot cho phía máy chủ (backend) và Vue.js cho phía khách hàng (frontend). Giải pháp này tận dụng ưu điểm của mô hình tách biệt giao diện và xử lý logic, đảm bảo hiệu suất và tính bảo mật.

stack Công Nghệ Sử Dụng

Để đảm bảo tính ổn định và hiệu quả, hệ thống được xây dựng dựa trên các công cụ và phiên bản cụ thể sau:

  • Môi trường phát triển (IDE): IntelliJ IDEA hoặc Eclipse.
  • Ngôn ngữ lập trình: Java (phiên bản 1.8 trở lên).
  • Framework Backend: Spring Boot.
  • Framework Frontend: Vue.js.
  • Cơ sở dữ liệu: MySQL 5.7.
  • Quản lý phụ thuộc: Maven 3.6.1.
  • Công nghệ web: HTML5, CSS3, JavaScript.

Phân Tích Khả Thi Kỹ Thuật

Việc lựa chọn Spring Boot kết hợp với Vue.js và MySQL mang lại nhiều lợi ích chiến lược. Spring Boot giúp giảm thiểu cấu hình thủ công thông qua cơ chế tự động cấu hình (auto-configuration), cho phép triển khai nhanh chóng các dịch vụ RESTful. Vue.js cung cấp khả năng phản hồi dữ liệu thời gian thực (reactive data binding), giúp giao diện người dùng cập nhật ngay lập tức khi có thay đổi mà không cần tải lại trang. MySQL đóng vai trò là hệ quản trị cơ sở dữ liệu quan hệ ổn định, đảm bảo tính toàn vẹn và bảo mật cho dữ liệu người dùng.

Hơn nữa, kiến trúc này hỗ trợ tốt việc phát triển API, cho phép frontend và backend giao tiếp độc lập. Điều này tạo điều kiện thuận lợi cho việc bảo trì, nâng cấp và mở rộng hệ thống trong tương lai khi lượng người dùng tăng lên.

Giới Thiệu Các Framework Chính

1. Spring Boot

Spring Boot là một framework giúp đơn giản hóa việc khởi tạo và phát triển ứng dụng Spring. Điểm mạnh lớn nhất của nó là khả năng nhúng sẵn các máy chủ web như Tomcat hoặc Jetty, loại bỏ nhu cầu triển khai file WAR riêng biệt. Cơ chế "Convention over Configuration" giúp developers tập trung vào logic nghiệp vụ thay vì các file cấu hình XML phức tạp.

Dưới đây là ví dụ về lớp khởi tạo ứng dụng và một endpoint kiểm tra trạng thái:


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class SocialPlatformApplication {

    public static void main(String[] args) {
        SpringApplication.run(SocialPlatformApplication.class, args);
    }

    @GetMapping("/api/health")
    public String checkStatus() {
        return "System Status: Online";
    }
}

Đoạn mã trên định nghĩa lớp chính `SocialPlatformApplication` với annotation `@SpringBootApplication`. Controller `checkStatus` trả về trạng thái hệ thống khi truy cập vào đường dẫn `/api/health`.

2. Vue.js

Vue.js là một framework tiến bộ cho việc xây dựng giao diện người dùng. Khác với các framework truyền thống, Vue sử dụng Virtual DOM để tối ưu hóa việc cập nhật giao diện. Khi dữ liệu thay đổi, Vue sẽ tính toán lại và chỉ cập nhật những phần tử DOM cần thiết, giúp tăng hiệu suất hiển thị.

Ví dụ minh họa cơ chế phản hồi dữ liệu trong Vue:


<!DOCTYPE html>
<html>
<head>
  <title>Vue Interaction Demo</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
  <div id="interface">
    <h3>Trạng thái: {{ statusText }}</h3>
    <button v-on:click="toggleStatus">Chuyển đổi</button>
  </div>

  <script>
    var vm = new Vue({
      el: '#interface',
      data: {
        statusText: 'Đang hoạt động'
      },
      methods: {
        toggleStatus: function() {
          this.statusText = this.statusText === 'Đang hoạt động' ? 'Tạm dừng' : 'Đang hoạt động';
        }
      }
    });
  </script>
</body>
</html>

Trong ví dụ này, biến `statusText` được liên kết với giao diện. Khi người dùng nhấn nút, phương thức `toggleStatus` thay đổi giá trị biến, và giao diện tự động cập nhật mà không cần thao tác DOM thủ công.

Luồng Nghiệp Vụ Hệ Thống

Quy trình hoạt động cơ bản của hệ thống bắt đầu từ việc đăng ký tài khoản. Người dùng mới cần cung cấp thông tin cá nhân để tạo hồ sơ. Sau khi đăng ký thành công, họ có thể đăng nhập bằng tên tài khoản và mật khẩu. Hệ thống sẽ xác thực thông tin này trước khi cấp quyền truy cập vào các tính năng chính như đăng bài, kết bạn hoặc quản lý hồ sơ.

Module quản lý người dùng cho phép administrator thực hiện các thao tác CRUD (Thêm, Xóa, Sửa, Xem) đối với các tài khoản. Mỗi tài khoản đều được gán vai trò cụ thể để kiểm soát quyền truy cập vào các tài nguyên hệ thống, đảm bảo an ninh thông tin.

Triển Khai Mã Nguồn: Xác Thực và Bảo Mật

Phần quan trọng nhất của hệ thống là cơ chế xác thực. Dưới đây là cách triển khai logic đăng nhập, tạo phiên làm việc và bộ lọc bảo mật.

Controller Xử Lý Đăng Nhập


@IgnoreAuth
@PostMapping("/authenticate")
public ApiResponse signIn(@RequestParam String account, 
                          @RequestParam String credential, 
                          HttpServletRequest request) {
    // Tìm kiếm người dùng dựa trên tài khoản
    UserAccount user = userRepository.findByAccount(account);
    
    // Kiểm tra tồn tại và mật khẩu
    if (user == null || !user.getPassword().equals(credential)) {
        return ApiResponse.error("Thông tin đăng nhập không hợp lệ");
    }
    
    // Tạo mã phiên làm việc
    String sessionId = securityService.createSessionToken(user.getId(), account, "users", user.getRole());
    return ApiResponse.success().put("sessionId", sessionId);
}

Dịch Vụ Tạo Token


@Override
public String createSessionToken(Long userId, String account, String tableName, String role) {
    // Kiểm tra token cũ
    SessionToken existingToken = tokenRepository.findByUserIdAndRole(userId, role);
    
    // Tạo chuỗi ngẫu nhiên duy nhất
    String newToken = UUID.randomUUID().toString().replace("-", "");
    
    // Thiết lập thời gian hết hạn (60 phút)
    Calendar calendar = Calendar.getInstance();   
    calendar.setTime(new Date());   
    calendar.add(Calendar.MINUTE, 60);
    
    if (existingToken != null) {
        existingToken.setTokenValue(newToken);
        existingToken.setExpireTime(calendar.getTime());
        tokenRepository.update(existingToken);
    } else {
        tokenRepository.insert(new SessionToken(userId, account, tableName, role, newToken, calendar.getTime()));
    }
    return newToken;
}

Bộ Lọc Kiểm Soát Truy Cập


@Component
public class AccessControlFilter implements HandlerInterceptor {

    public static final String AUTH_HEADER_KEY = "Authorization";

    @Autowired
    private SecurityService securityService;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // Cấu hình CORS
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));

        // Bỏ qua request OPTIONS
        if (request.getMethod().equals(RequestMethod.OPTIONS.name())) {
            response.setStatus(HttpStatus.OK.value());
            return false;
        }
        
        // Kiểm tra annotation bỏ qua xác thực
        IgnoreAuth annotation;
        if (handler instanceof HandlerMethod) {
            annotation = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class);
        } else {
            return true;
        }

        // Lấy token từ header
        String token = request.getHeader(AUTH_HEADER_KEY);
        
        if (annotation != null) {
            return true;
        }
        
        // Xác thực token
        SessionToken sessionData = null;
        if (StringUtils.isNotBlank(token)) {
            sessionData = securityService.getSessionData(token);
        }
        
        if (sessionData != null) {
            // Lưu thông tin vào session request
            request.getSession().setAttribute("uid", sessionData.getUserId());
            request.getSession().setAttribute("role", sessionData.getRole());
            request.getSession().setAttribute("account", sessionData.getAccount());
            return true;
        }
        
        // Trả về lỗi 401 nếu không xác thực
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
            writer.print(JSONObject.toJSONString(ApiResponse.error(401, "Yêu cầu đăng nhập")));
        } finally {
            if (writer != null) writer.close();
        }
        return false;
    }
}

Đoạn mã trên mô tả cơ chế bảo mật toàn diện. Annotation `@IgnoreAuth` cho phép các public API truy cập mà không cần token. Bộ lọc `AccessControlFilter` sẽ chặn các yêu cầu chưa xác thực, kiểm tra tính hợp lệ của mã phiên và thiết lập thông tin người dùng vào session nếu thành công. Nếu token không hợp lệ hoặc thiếu, hệ thống sẽ trả về mã lỗi 401.

Thẻ: spring-boot vuejs mysql java-web authentication

Đăng vào ngày 18 tháng 5 lúc 18:51