글 삭제시 유저가 입력한 패스워드와 작성자의 패스워드 일치시 삭제를 구현해야했는데 강의대로 따라가다보니 @DeleteMapping과 @RequestBody를 같이사용하게 되었다.
피드백
HTTP Method중 GET과 DELETE에서 RequestBody의 사용은 지양해야 합니다.
지금은 HTTP Method를 정의한 문서에서 GET과 DELETE에서 RequestBody(요청 본문)의 의미가 정의되어있지 않기 때문입니다.
다시말해 요청본문이 있어도 그것이 어떤역할을 해야할지 명확하지 않아 무시되거나 거부될 수 있습니다.
실무적인 관점에서는 사용하는 라이브러리/프레임워크/버전에 따라서 DELETE에 요청본문을 허용하지 않는 것들이 있습니다.
또한 일반적으로 DELETE에 요청본문을 넣지 않는다는 룰이 있어 다른 사람들과의 협업을 위해서도 다른 방식으로 Password를 전달해야합니다.
추가로 요청본문은 보이지 않아 보안적으로 더 좋다라는 오해를 받는데 브라우저의 개발자도구의 네트워크 탭에서 클라이언트가 서버로 어떤 데이터들을 전송했고, 어떤응답을 받았는지 모두 확인이 가능합니다. 따라서 보안을 위해 요청본문에 데이터를 넣는다는 것은 근거가 빈약하다고 할 수 있습니다.
DELETE,GET에서 Request Body를 지양해야 하는 이유
1. HTTP 명세상 정의되지 않음
HTTP 명세에 따르면
- GET과 DELETE 메서드는 요청 본문(Request Body)의 의미가 정의되어 있지 않음
- 즉, 본문이 존재하더라도 서버가 어떻게 해석해야 하는지 표준이 없음
즉, 어떤 서버는 Body를 무시하고,어떤 서버는 에러를 발생시키며,어떤 서버는 프레임워크에 따라 동작이 달라질 수 있다.
예시
- Spring Boot → 기본적으로 DELETE body 허용하지만, 일부 버전/설정에서는 무시됨
- Express.js, Flask → DELETE body 기본적으로 읽지 않음
- nginx reverse proxy → DELETE 요청의 body를 drop(삭제)시켜버림
2. REST 와 불일치
REST는 각 메서드의 역할이 명확해야함
| 메서드 | 역할 | 본문(body) | 목적 |
| GET | 조회 | ❌ 없음 | 서버 리소스 가져오기 |
| POST | 생성 / 작업 요청 | ✅ 가능 | 서버에 데이터 전달 |
| PUT | 전체 수정 | ✅ 가능 | 리소스 대체 |
| PATCH | 부분 수정 | ✅ 가능 | 리소스 일부 변경 |
| DELETE | 삭제 | ⚠️ 명세상 불명확 | 리소스 제거 요청 |
“리소스를 지워달라”는 신호만 보내는 게 DELETE의역할
추가 데이터를 실어 보내는 메서드로 설계X
그래서 Body를 붙이는 순간 이미 DELETE의 의미가 POST에 가까워진다.
생각해본 해결 방안
1. 쿼리스트링
- 쿼리스트링을 사용해 password=123123!! 이런식으로 받음
문제
- 유저가 보는 화면에서부터 민감한 개인정보를 확인할 수 있는 치명적인 단점 존재
2. Header에 담기
- 유저가 입력한 패스워드를 클라이언트가 헤더에 담아줌
문제
- 헤더는 요청의 상태/의도/형식/인증정보등의 메타데이터를 서버에게 전달하는 용도이다. 실제 데이터는 구조상 의도에 안맞음
3. 비밀번호 검증과 삭제 엔드포인트 분리
- 비밀번호 검증 Post 요청과 리소스 삭제 Delete 요청을 분리
문제
- 삭제 엔드포인트만 url 탈취되면 원치않는 데이터가 삭제될 위험성 있음
4. Post 메소드 사용
- 내가 기존지식으로 알고있던 내용. 애매할경우, 작업요청시 Post
문제
- 리소스 제거 엔드포인트인데 Post라서 Restful 하지 않음
내가 선택한 해결 방법
POST
의미적인 이유
- 비밀번호는 요청 본문 Body에 담아 서버로 넘겨야 한다.
- Post는 리소스 생성, 서버 작업요청시 사용하는데 Post만이 payload에 자유롭게 넘겨 보낼 수 있다.
보안적인 이유
- POST 본문은 HTTPS 통신 시 완전히 암호화되어 전송
- URL과 Header처럼 로그 남을 일이 없음
REST 관점
- 삭제는 리소스 삭제이니 DELETE가 맞지만 비밀번호 확인의 추가 검증 로직이 붙으면 단순 리소스 삭제로 볼 수 없다
- 삭제를 요청한다는 의미로 POST를 쓰는 것이 명세 위반은 아님, url에 삭제메소드의 표현을 적어주면 됨
POST /schedules/{id}/delete
결론
비밀번호 확인 후 삭제 처럼 부가 검증이 필요한 삭제는 POST /{id}/delete 방식이 가장 명확하다고 생각했다.
REST 명세를 살짝 벗어나더라도 실제 서비스에서는 이 접근이 더 실용적이다.
'Dev. > Spring' 카테고리의 다른 글
| [Spring] Filter (0) | 2025.11.13 |
|---|---|
| [Spring] JPA 영속성 컨텍스트 (0) | 2025.11.10 |
| [Spring] JPA N+1 문제 (0) | 2025.11.07 |
| [Spring] JPA 관계 설정(1:N/N:1) (0) | 2025.11.05 |
| [Spring] 수정 사항 발생시 자동 리빌드 Auto Reload (0) | 2025.11.04 |