1. 개요
기존의 웹 애플리케이션에서 로그인하려면 일반적으로 인증을 위해 서버에 사용자 이름과 암호를 보내야 합니다. 이러한 요소는 이론적으로 GET 요청의 URL 매개변수가 될 수 있지만 POST 요청으로 캡슐화하는 것이 훨씬 낫습니다.
하지만 GET 요청은 민감한 정보를 보낼 필요가 없기 때문에 로그아웃이 가능해야 할까요?
이 사용방법(예제)에서는 이 설계 고려 사항의 다양한 측면을 살펴보겠습니다.
2. 서버 측 세션
서버 측 세션을 관리할 때 해당 세션을 제거하기 위해 Endpoints을 노출해야 합니다. 단순성 때문에 GET 메서드를 사용하고 싶은 유혹을 느낄 수 있습니다. 물론 이것은 기술적으로는 작동하지만 일부 바람직하지 않은 동작을 유발할 수 있습니다.
사용자를 위해 GET 링크를 미리 가져오는 웹 가속기 와 같은 일부 프로세스가 있습니다 . 미리 가져오기의 목적은 사용자가 해당 링크를 따라갈 때 콘텐츠를 즉시 제공하여 페이지 로딩 시간을 줄이는 것입니다. 이러한 프로세스 는 GET 링크가 어떤 것의 상태를 변경하는 것이 아니라 콘텐츠를 반환하기 위한 것이라고 가정합니다.
로그아웃을 GET 요청으로 노출하고 이를 링크로 표시하면 페이지에서 링크를 프리페치하려고 시도하는 동안 이러한 프로세스가 실수로 사용자를 로그아웃시킬 수 있습니다.
예를 들어 로그아웃 URL이 javascript에 의해 결정되는 것과 같이 정적으로 사용할 수 없는 경우에는 문제가 되지 않을 수 있습니다. 그러나 HTTP/1.1 RFC 는 GET 메서드는 콘텐츠를 반환하는 데만 사용해야 하며 사용자는 GET 요청의 부작용에 대해 책임을 질 수 없다고 명시하고 있습니다. 가능하면 이 권장 사항을 따라야 합니다.
대조적으로, RFC는 데이터 처리 프로세스(로그아웃)에 데이터(세션 또는 세션 ID)를 제출할 수 있는 것으로 POST 메서드를 설명합니다. 이것은 우리가 성취하고자 하는 것에 대한 더 적절한 설명입니다.
2.1. 스프링 시큐리티
기본적으로 Spring Security는 로그아웃 요청이 POST 유형이어야 합니다. 그러나 CSRF 보호 를 비활성화하면 Spring이 GET 로그아웃 요청을 사용하도록 할 수 있습니다 .
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
...
}
3. 상태 비저장 REST
상태 비저장 REST 세션을 관리할 때 "로그아웃" 개념이 변경됩니다. 상태 비저장 환경에서 모든 요청에는 전체 세션이 포함됩니다. 따라서 어떠한 종류의 요청도 보내지 않고 Javascript를 사용하여 세션을 버리기만 하면 "로그아웃"이 가능합니다.
그러나 Security상의 이유로 해지된 JWT를 블랙리스트에 추가하려면 로그아웃 작업을 서버에 계속 알려야 합니다. 이것은 "로그아웃" 후 세션이 사용되는 것을 방지합니다.
상태 비저장 환경에서도 로그아웃 시 서버에 요청을 보내야 합니다. 이러한 요청의 의도는 콘텐츠를 검색하는 것이 아니므로 GET을 통해 요청하면 안 됩니다. 대신 로그아웃하겠다는 명시적인 의도를 가지고 세션을 서버에 게시해야 합니다.
4. 결론
이 짧은 토론에서 우리는 로그아웃이 GET인지 POST인지에 대한 일반적인 디자인 질문을 간략하게 살펴보았습니다.
이 문제의 다양한 측면을 고려했습니다.
- 의미상 GET 요청에는 상태 저장 부작용이 없어야 합니다.
- 프리페칭 링크를 포함하여 사용자가 브라우저에서 실행할 수 있는 프로세스가 있습니다. 로그아웃이 GET을 통해 발생하는 경우 사전 가져오기 프로세스가 로그인 후 실수로 사용자를 로그아웃시킬 수 있습니다.
- 무상태 세션도 POST 요청을 통해 수행되어야 하는 로그아웃 이벤트를 서버에 보고해야 합니다.