개발 etc

로그인, 로그아웃에는 무슨 HTTP 메소드를 써야할까?

묠니르묘묘 2022. 4. 6. 15:06

일단 먼저 HTTP에 대해 간단하게 보자.

 

HTTP 메소드 종류

1. GET : 리소스 조회

  • 서버에 전달하고 싶은 데이터는 query(쿼리 파라미터, 쿼리 스트링)으로 전달
  • 메시지 바디를 사용할 순 있지만, 지원하지 않는 곳도 많아서 권장X

2. POST : 요청 데이터 처리, 주로 등록에 사용

  • 메시지 바디를 통해 서버로 요청 데이터 전달
  • 메시지 바디를 통해 들어온 데이터를 처리하는 모든 기능 수행 (만능)
  • 주로 전달된 데이터로 신규 리소스 등록, 프로세스 처리에 사용됨

3. PUT : 리소스를 전부 교체할 때

  • 리소스를 대체하고, 없으면 생성 (새로운 것으로 덮는다)
  • 클라이언트가 리소스를 식별하여, 리소스 위치를 알고 URI 지정 (POST와 차이점)

4. PATCH : 리소스 부분 변경 (리소스가 존재해야함.)

5. DELETE : 리소스 삭제

 

https://ko.wikipedia.org/wiki/HTTP

 

 

 

클라이언트에서 서버로 데이터 전송 방법

  1. 쿼리 파라미터를 통한 데이터 전송 (GET)
  2. 메시지 바디를 통한 데이터 전송 (POST, PUT, PATCH)

 

 

 

HTTP API 설계 예시

  • 회원 목록 /members → GET
  • 회원 등록 /members → POST
  • 회원 조회 /members/{id} → GET
  • 회원 수정 /members/{id} → PATCH, PUT, POST
  • 회원 삭제 /members/{id} → DELETE

 

 

 

🧐 로그인과 로그아웃 때는 HTTP 메소드 중 무엇을 써서 요청을 보내야 할까?

메서드의 의도와 달리 실제로 그 요청을 받고 동작하는 서버에서는 구현을 다르게 할 수 있다.

하지만 이는 HTTP 메소드의 의도(관례)를 깨트리는 것이라고 볼 수 있다.

결국 HTTP는 클라이언트와 서버 사이의 인터페이스 역할을 하는 것이고, 실제로 구현을 어떻게 할지는 개발자에게 달려있다.

 

HTML FORM 전송은 GET과 POST만 지원한다.

이 때는 메서드의 정의와 꼭 맞게 사용하고 있지 않게 된다.

GET이든 POST이든 HTTP 프로토콜을 사용하면 내부 데이터는 패킷으로 전송되기에 다 노출된다.

결국 HTTPS나 전송 구간간에 암호화를 하는 것이 중요하다.

일부 웹서버나 방화벽에서 PUT, DELETE, HEAD 등 메서드를 허용하지 않을 수 있다.

API 서버를 제작할 때도 그렇고, 보통 GET과 POST만 허용하도록 만드는 경우가 있다.

 

Spring Security문서에서는 GET이 CSRF 공격에 취약하기에 POST 요청이 선호된다고 명시되어 있다.

따라서 로그인 시에는 POST를 써서 ID와 PW가 body에 담겨서 보내지는데 이것을 HTTPS를 적용하면 암호화가 된다.

GET은 모든 사람에게 표시되는 쿼리 스트링으로 URL 요청이 보내지기에 로그인은 POST를 쓴다.

Spring Securty는 로그인, 로그아웃 요청이 POST유형이지만, CSRF 보호를 비활성화하면 GET으로 로그아웃 요청을 사용할 수 있다.

 

현재 프로젝트에서는 로그인을 Access Token과 Refresh Token이라는 토큰 인증 방식을 사용한다.

Refresh Token을 쿠키에 저장하여 로그인을 유지하는데 httpOnly를 사용하여 서버에서만 쿠키를 재설정할 수 있다.

이 때는 사용자가 직접 수동으로 지우는 것 외에는 서버에서 삭제하여 로그아웃을 할 수 밖에 없다.

즉, 로그아웃을 하려면 서버에 HTTP 요청을 보내야 한다.

 

StackOverFlow 등에서 여러 글들을 찾아보았는데 GET일 때는 prefetch로 인한 GET단점도 존재한다고 한다.

사용자를 위해 Web Acceleration 또는prefetch로 사용자가 클릭할 가능성이 있는 링크를 가정하여 미리 가져와 페이지 로딩 시간을 줄이는 기술이다. 이런 프로세스는 GET 링크가 콘텐츠를 반환하기 위해서지 상태를 변경하기 위한 것이 아니기 때문에 한 것이라고 한다.

이 때 GET으로 로그아웃을 만들어 놓는다면 강제 로그아웃이 될 지도 모른다.

HTTP/1.1 RFC에서는 GET메서드는 콘텐츠 반환하는데만 사용해야하며 사용자는 GET 요청의 부작용에 대해 책임을 질 수 없다고 분명히 명시하고 있다. 그러므로 가능하면 이 권장 사항을 따라야한다.

 

이를 통해 GET 요청 시 상태 저장 부작용은 없어야하고,

브라우저에서 prefetch를 포함하는 프로세스를 실행할 수도 있다.

GET을 통해 로그아웃을 할 때 prefetch 프로세스가 강제로 로그아웃시킬 수 있다.

토큰, 세션 등 StateLess 상태에서도 서버에서 BlackList라든지 사용할 때 서버에 요청해야하므로 POST를 사용하는 것이 낫다고 본다.

 

 

결론

쿠키 또는 세션을 삭제하기에 정보의 변경이 없다는 GET 사용! (비추천)

쿠키 또는 세션을 삭제하는 의미이기에 RESTful한 요청으로 DELETE 사용!

진정한 의미의 RESTful 요청은 POST 사용!

 

 

 

 


https://www.baeldung.com/logout-get-vs-post

https://stackoverflow.com/questions/33294409/how-to-define-http-method-and-status-code-of-login-and-logout

https://stackoverflow.com/questions/5868786/what-method-should-i-use-for-a-login-authentication-request

https://stackoverflow.com/questions/40245154/http-restful-webservice-logout-which-is-correct-or-better-practice-post-or-de

https://stackoverflow.com/questions/3521290/logout-get-or-post

https://stackoverflow.com/questions/36294359/is-logout-useless-on-a-rest-api