Giải thích giùm mình đoạn code Spring

Mình có 1 đoạn code Spring, nhưng mình không hiểu ý nghĩa của đoạn code này. Bạn nào giải thích giùm mình với(Theo từng dòng thì càng tốt):

@Component
// We want to put this in front of SpringSessionFilter
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RequestFilter {

	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		
		response.setHeader("Access-Control-Allow-Origin", "*");
		response.setHeader("Access-control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
		response.setHeader("Access-Control-Allow-Headers", "x-requested-with, x-auth-token");
		response.setHeader("Access-Control-Max-Age", "3600");
		response.setHeader("Access-Control-Allow-Credentials", "true");
		
		if(!(request.getMethod().equalsIgnoreCase("OPTIONS"))) {
			try {
				chain.doFilter(req, res);
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else {
			System.out.println("Pre-fight");
			response.setHeader("Access-Control-Allowed-Methods", "POST, GET, DELETE");
			response.setHeader("Access-Control-Max-Age", "3600");
			response.setHeader("Access-Control-Allow-Headers", "authorization, content-type, x-auth-token, " +
                    "access-control-request-headers,access-control-request-method,accept,origin,authorization,x-requested-with");
			response.setStatus(HttpServletResponse.SC_OK);
		}
	}
	
	public void init(FilterConfig filterConfig) {}
	
	public void destroy() {}

}

Và đây là giải thích cho đoạn code trên:

So when Angular 2 send an http post ajax call, it will first send a pre-flight and method type is not “POST” but “OPTIONS”. If this preflight has a valid response, then it will start to send the real http post. This is to prevent cross site attack. At backend, spring doesn’t have a out-of-box handling for this. So we need to check whether the http method is a preflight or not. If it is, we will just respond with valid headers and info. If not, we’ll just proceed the filter chain.

Mình không vào giải thích cho bạn.Nhưng mình nghĩ bạn nên học java web servlet thuần trước thì sẽ hiểu.

2 Likes

Cái này là HTTP spec (đúng hơn là chỉ có browser làm ntn).

2 Likes

Tôi rất muốn trả lời đầy đủ cho bạn, nhưng có lòng mà không có sức vì để trả lời đầy đủ và chi tiết đoạn mã trên, tôi nghĩ chắc phải viết vài trăm trang giấy.

Tuy nhiên, tôi cố gắng để giải thích ngắn gọn cho bạn như sau: Đoạn mã này có thể được chia thành hai phần để tìm hiểu như sau:

  1. Mỗi câu lệnh có tác dụng gì? Ví dụ như
    response.setHeader("Access-Control-Allow-Origin", "*");
    để làm gì?
  2. Và toàn bộ đoạn mã này làm việc như thế nào? Hay nói cách khác, logic của đoạn mã này là gì?

Xét về tổng thể, tôi không đồng ý lắm với bạn @hoangltse04739 là phải học về Java Servlet mới hiểu được đoạn mã này do nó tương đối độc lập với ngôn ngữ. Logic của đoạn mã này có thể được viết bằng nhiều ngôn ngữ khác nhau (C#, Python, Ruby, v.v.). Như phần trích dẫn bạn gởi kèm theo, mục đích của đoạn mã này là để ngăn ngừa khả năng bị tấn công bằng Cross Site Scripting (hay XSS). Do đó, để hiểu được nó, tôi đề nghị bạn chịu khó học một số chủ đề sau:

Nói một cách ngắn gọn, đoạn mã trên giải quyết vấn đề XSS bằng cách xác nhận độ tin cậy của các HTTP Message từ browser theo hai bước:

  1. Client (JavaScript từ browser) sẽ phải gởi một HTTP Request với verb OPTION về Web server. Khi Web Server nhận được request này, nó sẽ trả về một response với một số tham số nhất định trong HTTP Header (trong phần else)
  2. Khi client nhận được response từ Server với các tham số này, nó hiểu rằng nó được cho phép để chính thức gởi một request với các dữ liệu cần thiết cho server.

Bởi ví quá trình này gồm 2 bước và đòi hỏi xác nhận của Server trong bước đầu tiên, nên cách thức tấn công bằng XSS bị vô hiệu hóa. Phần front-end và back-end của quá trình này có thể được implement bằng các ngôn ngữ và framework bất kỳ (bạn nói là phần front-end trong ví dụ này viết bằng Angular, nhưng nó có thể được viết bằng bất cứ framework Front-end nào khác. Và tương tự như vậy, ở Back-end, không bắt buộc nó phải được viết bằng Spring).

Tổng thể là như thế, nhưng để hiểu chi tiết thì bạn chịu khó đọc các thông tin mà tôi gợi ý nhé. Như tôi có nói trong một số trả lới trước đây, để trở thành một người làm IT giỏi thì trước khi học các ngôn ngữ lập trình, các bạn phải học giỏi tiếng Anh.

Trên Stackoverflow cũng có một số thảo luận về vấn đề này, bạn có thể đọc để hiểu thêm:

https://stackoverflow.com/questions/40497399/http-request-from-angular-will-send-with-method-options-instead-of-post

https://stackoverflow.com/questions/29954037/why-is-an-options-request-sent-and-can-i-disable-it (link này có một biểu đồ về CORS rất hữu ích)

https://stackoverflow.com/questions/1256593/why-am-i-getting-an-options-request-instead-of-a-get-request

5 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?