RequestBodyAdvice의 사용법에 대해 묻는 사람이 있어 이에 대해 글을 쓰게 되었습니다.
암호화 및 복호화 자체는 어렵지 않지만, 언제 처리해야 할까요? 필터를 정의하여 요청과 응답을 각각 가로채 처리하는 것도 가능하지만 이 방법은 거칠지만 유연합니다. 왜냐하면, 첫 번째 손에 요청 매개 변수와 응답 데이터를 얻을 수 있기 때문입니다. 그러나 SpringMVC에서는 ResponseBodyAdvice와 RequestBodyAdvice를 제공하여 요청과 응답을 사전 처리할 수 있도록 지원합니다.
그래서 오늘 이 글은 두 가지 목적을 가지고 있습니다:
매개 변수/응답 암호화 및 복호화에 대한 아이디어 공유.
ResponseBodyAdvice와 RequestBodyAdvice의 사용법을 공유합니다.
그러면 이제 본론으로 들어가 보겠습니다.
1.개발 암호화 starter
우리가 개발하는 이 도구를 보다 일반화하기 위해, 그리고 스프링 부트 스타터를 직접 정의하기 위해 이 도구를 starter로 만들겠습니다. 이후에는 Spring Boot 프로젝트에서 바로 사용할 수 있습니다.
먼저 Spring Boot 프로젝트를 생성하고, spring-boot-starter-web 의존성을 추가합니다.
의존성을 추가한 후에는 미리 사용할 수 있도록 암호화 유틸리티 클래스를 정의합니다. 암호화 방법에는 대칭 키 암호화와 비대칭 키 암호화가 있으며, 대칭 키 암호화에서는 AES, DES, 3DES 등 다양한 알고리즘이 사용됩니다. 여기에서는 Java에서 제공하는 Cipher를 사용하여 대칭 키 암호화 방식 중 AES 알고리즘을 사용합니다.
이 Utils 클래스는 간단하므로 따로 설명은 필요하지 않을것 같습니다. 그러나 암호화된 데이터는 가독성이 없을 수 있으므로 일반적으로 암호화된 데이터를 Base64 알고리즘을 사용하여 인코딩하여 읽을 수 있는 문자열을 얻을 수 있습니다. 다시 말해서, 위의 AES 암호화 메소드의 반환 값은 Base64로 인코딩 된 문자열입니다. AES 복호화 메소드의 매개 변수도 Base64로 인코딩 된 문자열이며, 이 문자열을 먼저 디코딩 한 다음 해독해야합니다.
그 다음 우리는 예비로 응답 도구 클래스를 패키징 할 것입니다. 이것은 사람들이 종종 송건 비디오를보고 이미 잘 이해할 것입니다.
supports: 이 메서드는 어떤 유형의 인터페이스가 암호화되어야 하는지를 판단하기 위해 사용됩니다. returnType 매개 변수는 반환 유형을 나타내며, 여기에서 판단 로직은 해당 인터페이스에 @Encrypt 주석이 포함되어 있는지 여부입니다. 있으면 해당 인터페이스는 암호화 처리가 필요하며, 없으면 해당 인터페이스는 암호화 처리가 필요하지 않습니다.
beforeBodyWrite: 이 메서드는 데이터 응답 전에 실행됩니다. 즉, 우리는 응답 데이터를 먼저 두 번째 처리하고 처리가 완료되면 json으로 반환합니다. 여기에서는 처리 방법이 매우 간단합니다. RespBean의 status는 상태 코드이므로 암호화하지 않아도됩니다. 두 개의 다른 필드를 다시 암호화하고 다시 값을 설정하면됩니다.
주의!사용자 정의 ResponseBodyAdvice는 @ControllerAdvice 주석을 사용하여 표시해야합니다.
DecryptRequest 클래스에서는 RequestBodyAdvice 인터페이스를 직접 구현하는 대신 RequestBodyAdviceAdapter 클래스를 상속합니다. RequestBodyAdviceAdapter 클래스는 RequestBodyAdvice 인터페이스의 하위 클래스이며, 인터페이스의 일부 메서드를 구현하므로 RequestBodyAdviceAdapter를 상속하면 실제 요구 사항에 따라 일부 메서드만 구현하면됩니다.
supports: 이 메서드는 어떤 인터페이스가 인터페이스 복호화를 처리해야 하는지를 판단하기 위해 사용됩니다. 여기에서 판단 로직은 @Decrypt 주석이 메서드 또는 매개 변수에 포함되어 있는지 여부입니다. 복호화 문제를 처리합니다.
beforeBodyRead: 이 메서드는 매개 변수가 구체적인 객체로 변환되기 전에 실행됩니다. 먼저 데이터를 스트림에서 로드한 다음 데이터를 복호화하고 복호화가 완료되면 HttpInputMessage 객체를 다시 구성하여 반환합니다.
사용은 어떻게?
publicclassUser{
private Long id;
private String username;
//생략 getter/setter
}
@RestControllerpublicclassHelloController{
@GetMapping("/user")@Encryptpublic RespBean getUser(){
User user = new User();
user.setId((long) 99);
user.setUsername("javaboy");
return RespBean.ok("ok", user);
}
@PostMapping("/user")public RespBean addUser(@RequestBody@Decrypt User user){
System.out.println("user = " + user);
return RespBean.ok("ok", user);
}
}