최근에 보안권고 중에 GET/POST만 사용하고, PUT/DELETE를 포함한 나머지 모든 메소드를 차단하라는 권고를 봤다.
요즘 API 추세는 GET/POST/PUT/DELETE를 모두 사용하는 추세인데 두개만 쓰라니...
당황 스러웠는데...
Servlet specification에 POST만 form field에 접근할 수 있도록 제한해 두었단다..PUT은 안되고...
즉, PUT으로 form 데이터를 보내면 ServletRequest.getParameter*() 호출을 했을 때 값을 못 읽어온단다...
spring framework에서는 3.1부터 이 문제 해결을 위해 HttpPutFormContentFilter를 도입했다고 한다.
흠..REST 한답시고 ajax를 이용해 PUT으로 호출을 해봤으면 이 문제를 알았을텐데...뭐 이렇게 놓고보면 보안권고에서 "쓸데없는" PUT을 막으라고 한게 어느정도 이해는 된다....물론 이것때문에 PUT을 쓸데없다 한건지는 모르겠지만..
결국... Servlet specification을 따르는 form을 쏠 때 사용되는 content-type인 "application/x-www-form-urlencoded"를 사용한다면...
이것을 이용해서 ajax 호출을 하게 되면 PUT을 쓰는것 자체가 spec을 벗어난게 된다.
결론은... REST 스럽게 API를 구축할것이면 호출하는쪽이 브라우저가 아니라고 가정하는게 합리적인거고,
content-type이 "application/x-www-form-urlencoded"인 쪽보다는 "*/json" 혹은 "*/xml" 형태인 것이 더 적합해 보인다는거고...
Spring의 controller에서도 @ResponseBody로 받는 쪽이 더 적절하다는거다...
근데 또 골치아픈건, 사람들은 습관적으로 content-type에 "application/x-www-form-urlencoded"를 넣어서 던질텐데, 서버에서 이걸 받아준다면 PUT 호출 들어왔을 때 뻔한 문제가 발생해서 client가 삽질할 것이고,(위의 filter를 안쓴다는 가정 하에)
"application/x-www-form-urlencoded"를 무조건 튕겨내 버리면 그것도 곤란하고....
사실 현실적으로 "상식적인 상황"이라면...
브라우져에서 json/xml으로 호출하는 경우는 URL에 직접 넣은 GET 방식일 때 뿐일 것이다.
브라우져에서 PUT/POST로 json/xml을 호출한다는건 이미 submit 버튼 눌러 곧바로 요청했다기보다 ajax를 이용해 호출됐다고 봐야한다.
ajax는 이미 api client라고 봐야 하기 때문에 이걸 굳이 form과 같은 content-type으로 호출할 필요는 없어보인다.
ㄴ form 태그에 enctype이라는 이름으로 content-type을 지정할 수 있게 되어 있긴 하지만, spec상 세가지만 쓸 수 있어서 "*/json", "*/xml"류를 쓰는건 spec에 어긋난다. (http://www.w3.org/TR/html5/forms.html#attr-fs-enctype)
결론은?
브라우져에서 직접 들어오는 경우(주소창 입력=GET, form submit=POST)가 아닌 ajax 호출에서는
json 혹은 xml에 맞는 content-type을 넣어주고,
controller에서도 @ResponseBody+@RequestBody 쌍을 이용해 처리하는게 깔끔하다.
브라우져에서 직접 들어오는 경우라고 한다면 브라우져 답게 GET/POST만 사용하고.
이렇게 함으로써 Servlet Specification과 RESTful 사이에 어설프게 껴벼린 PUT의 처리를 고민할 필요가 사라지....지 않을까?
'SW-PRODUCT > 개발-웹닭·HTTP' 카테고리의 다른 글
Spring validation - @ResponseBody (0) | 2014.12.23 |
---|---|
Cookie.HttpOnly (0) | 2014.11.15 |
[Spring] 하나의 TransactionManager에 여러 dataSource 담기!! (0) | 2014.02.28 |
초간단 웹서비스 띄우기 (0) | 2013.08.07 |
10진수 / 36진수 / 62진수 (0) | 2013.07.25 |