로그 아웃 : GET 또는 POST?


434

이 질문은 일반적으로 GET 또는 POST를 언제 사용해야하는지에 관한 것이 아닙니다. 웹 응용 프로그램에서 로그 아웃을 처리하는 데 권장되는 정보입니다. 일반적인 의미에서 GET과 POST의 차이점에 대한 많은 정보를 찾았지만이 특정 시나리오에 대한 명확한 대답을 찾지 못했습니다.

실용 주의자로서 GET을 사용하는 경향이 있습니다. POST를 구현하는 것이 훨씬 간단하기 때문입니다. 간단한 링크를 삭제하면됩니다. 이것은 적어도 내 머리 꼭대기에서 생각할 수있는 대다수의 웹 사이트의 경우처럼 보입니다. 스택 오버 플로우조차도 GET으로 로그 아웃을 처리합니다.

나를 주저하게 만드는 것은 일부 웹 액셀러레이터 / 프록시가 페이지에서 찾은 모든 링크를 찾아서 검색하여 페이지를 미리 캐시한다는 (오래된) 주장입니다. 따라서 사용자는 클릭 할 때 더 빠른 응답을 얻습니다. 이것이 여전히 적용되는지 확실하지 않지만, 이것이 사실이라면 이론적으로 이러한 액셀러레이터 중 하나를 가진 사용자는 로그인하자마자 응용 프로그램에서 쫓겨날 것입니다. 클릭하지 않아도 링크가 표시됩니다.

지금까지 읽은 모든 내용은 POST가 "파괴적 조치"에 사용되어야하지만 애플리케이션과 같은 쿼리의 내부 상태를 변경하지 않는 조치는 GET으로 처리되어야한다고 제안합니다 . 이를 바탕으로 실제 질문은 다음과 같습니다.

응용 프로그램에서 로그 아웃하면 파괴적인 행동으로 간주됩니까 / 응용 프로그램의 내부 상태를 변경합니까?


글쎄, 당신이 처음으로 사이트를 방문하고 로그 아웃 링크가 없다고 가정하면 로그인 할 때 로그 아웃됩니다. 로그 아웃 URL이 이미 캐시되어 있기 때문에 두 번째로 로그인 한 후에는 문제가 없습니다. 그러나 적절한 액셀러레이터가 대부분의 로그 아웃 URL을 필터링 할 수 있다고 가정 할 수 있습니다.
HyperCas

2
HyperCas, 로그 아웃 URL을 필터링하는 가속기는 내가 고려한 이론이자 질문을 게시하기로 결정한 이유 중 하나였습니다. 액셀러레이터 논리를 신뢰하는 것이 조금 꺼려하고 언젠가는 엉터리 액셀러레이터를 사용하는 사용자가 로그인 할 수 없다고 불평합니다. 이들이 표준을 따르는 지 또는 그러한 표준이 존재하는지 알고 있습니까?
Daniel Liuzzi

양식을 자동으로 제출 한 액셀러레이터 (예 : 맬웨어)는 맬웨어 IMO입니다. 액셀러레이터가 양식을 자동으로 제출한다고 생각하는 것은 전적으로 비논리적입니다. Google을 방문한다고 상상해보십시오. 검색 양식을 어떻게 제출할 수 있습니까? 아무도 예측할 수없고 규칙을 따르지 않기 때문에 아무도 악성 코드를 설명 할 수 없습니다.
Alex

3
@AlexW-내 질문을 오해했다고 생각합니다. 내가 제안한 액셀러레이터 시나리오는 POST가 아닌 GET을 사용할 때 가능한 문제를 보여주기 때문에 게시 할 양식이 없으며 액셀러레이터가 문제를 일으키지 않는 일반 링크 만 있습니다.
Daniel Liuzzi

1
나는 이것에 대해 너무 늦었다는 것을 알지만 Alex는 Daniel이 요구하는 것이 아닙니다. 그는 사용자가 로그 아웃 링크를 클릭하고 액셀러레이터가 응용 프로그램에 충돌하지 않고 캐시 된 로그 아웃 페이지를 반환하면 사용자는 로그인 상태를 유지하게된다고합니다. 어쨌든
Rob Grant

답변:


475

사용하십시오 POST.

2010 년에는 GET아마도 사용 이 용인되었을 것입니다. 그러나 오늘날 (2013 년) 브라우저는 다음에 방문 할 "생각하는"페이지를 미리 가져옵니다.

다음은 Twitter 에서이 문제에 대해 이야기하는 StackOverflow 개발자 중 하나입니다.

편리한 URL 프리 페칭을 위해 GET 요청을 로그 오프 한 Chrome 팀과 Chrome 팀에 감사의 말씀을 전합니다.-Nick Craver ( @Nick_Craver ) 2013 년 1 월 29 일

재미있는 사실 : StackOverflow는 GET을 통한 로그 아웃을 처리하는 데 사용되었지만 더 이상은 아닙니다.


2
이 업데이트에 감사드립니다, Dave. 나는 심지어 로그를 POST로 전환 한 것을 알지 못했고 크롬에는 프리 페치가 내장되어 있다는 단서가 없었습니다. 마지막으로 인용 한 트위트는 내가 설명 한 문제에 대한 더 나은 예를 제공 할 수 없었습니다. 내 질문과 내 의심을 확인합니다. 귀하의 답변에 투표하고 답변을 수락합니다.
Daniel Liuzzi

4
내 브라우저에서 유래 같은 외모를 로그 아웃 <LI> <a href="https://stackoverflow.com/users/logout">는 GET가 아닌 POST이다 </A> </ li>로 로그 아웃
boatcoder

9
@ Mark0978에서 링크를 클릭하십시오.
David Murdoch

2
흥미 롭군 아마도 가장 좋아하는 기능 중 하나 일 것입니다. 그런 다음 로그 아웃하면 확실합니다. 프리 페치에서 로그 아웃되는 것을 방지 할 수 있지만 Amazon, Ebay 및 Gmail은 모두 사용자에게 로그 아웃과 실제 로그 아웃 이벤트 사이에 트릭 페이지가없는 로그 아웃에 GET을 사용합니다. 나는 페이지 사이에 많은 사람들이 실수로 자신들이 로그 아웃했다고 믿게 될 것이라고 생각할 것이다. SO에 대한 문제는 최소한이며 돈이 들지 않으며 모든 것의 99 %가 공개됩니다.
보트 코더

7
@Red HTTP / 1.1 표준에 따르면 이는 브라우저의 결함이 아니라 서버의 결함입니다. GET은 서버 측에 부작용이 없을 것으로 예상됩니다. 이 표준은 "사용자가 부작용을 요청하지 않았기 때문에 책임을 질 수는 없다"고 말합니다.
eyuelt

45

REST에는 세션이 없어야하므로 삭제할 것이 없습니다. REST 클라이언트는 모든 요청에 ​​대해 인증합니다. 로그인 또는 로그 아웃은 환상 일뿐입니다.

당신이 정말로 요구하는 것은 브라우저가 모든 요청에 ​​대해 인증 정보를 계속 전송해야한다는 것입니다.

아마도 응용 프로그램이 로그인 한 것처럼 보이는 착각을 초래한다면 자바 스크립트를 사용하여 "로그 아웃"할 수 있어야합니다. 왕복 여행이 필요하지 않습니다.


수비 논문- 섹션 5.1.3

클라이언트에서 서버로의 각 요청에는 요청을 이해하는 데 필요한 모든 정보가 포함되어야하며 서버에 저장된 컨텍스트를 활용할 수 없습니다. 따라서 세션 상태는 전적으로 클라이언트에서 유지됩니다


1
나는 실제로 이것을 알지 못했다. 그런 다음 FormsAuthentication과 함께 ASP.NET MVC를 사용하고 있으며 세션에 의존하기 때문에 내 앱이 전혀 RESTful하지 않을 것 같습니다.
Daniel Liuzzi

19
그러나 실제로 로그인 정보는 httponly일부 xss 위험을 방지하기 위해 속성으로 표시된 쿠키에 보관됩니다. 이는 쿠키 를 수동으로 지우는 것보다 서버에서만 재설정 할 수 있음을 의미합니다.
Remus Rusanu

6
사용자의 '수동'은 브라우저 설정으로 이동하여 '쿠키 지우기'옵션을 선택합니다. 웹 사이트를 '로그 오프'할 수있는 방법은 거의 없습니다.
Remus Rusanu

1
@Remus Ahhh, 저명한 웹 브라우저로 웹 앱을 작성하는 것이 얼마나 고통 스러운지.
대럴 밀러

1
그러나 @DarrelMiller는 서버 측에서 JWT를 취소하지 않는 것은 보안 취약점입니다. 토큰이 서버에 저장되지 않은 경우에도 사용자가 로그 아웃 / 암호 변경 / 역할 / 퀴트 등을 변경하면 남용을 방지하기 위해 (최소한 만료 될 때까지) 블랙리스트에 포함되어야합니다.
java-addict301

38

GET여기서 남용 될 수있는 한 가지 방법 은 인터넷을 통해 사람 (경쟁자 :)이 src="<your logout link>"ANYWHERE 와 함께 이미지 태그를 배치하고 사이트 사용자가 해당 페이지를 우연히 발견 한 경우 무의식적으로 로그 아웃하는 것입니다.


4
아니요, 이것은 옳지 않습니다. 로그 아웃 링크는 올바른 쿠키 데이터가 전송 된 경우에만 작동하며 다른 쿠키는 아닙니다. 그리고 세션 ID가 URL에 저장되어 있어도 모든 세션에서 이러한 변경으로 작동하지는 않습니다.
Richard H

4
와우, 나는 그런 생각을하지 않았다! 그래서 GET을 사용하지 않는 또 다른 이유와 왜 모든 사람들이 그것을하는지 이해하지 못하는 다른 이유가 있습니다. 젠장, 이제 stackoverflow.com/users/logout "image"도 내 게시물을 포함하고 어떤 일이 일어나는지 확인하고 싶습니다 :-D
Daniel Liuzzi

24
src =는 간단한 브라우저 요청으로, 서버 측이 아니라 클라이언트에서옵니다. 모든 쿠키를 전달하며 사용자 IP에서 가져옵니다. 광고 추적 픽셀이 작동하는 이유입니다. 이러한 악용을 결정하는 유일한 방법은 리퍼러를 확인하는 것입니다.
raveren

12
SuperLogout.com 은 정확하게 ( /logout숨겨진 이미지로 URL을 로드 ) 작동하며 작동합니다.
Dan Dascalescu

9
re : SuperLogout ... 클릭 한 이유를 모르겠습니다.
MI Wright

21

정확히 말하면, GET / POST (또는 다른 동사)는 일부 리소스 (URL로 주소 지정)에 대한 작업이므로 일반적으로 응용 프로그램 상태가 아니라 리소스 상태에 대한 것입니다. 따라서 진정한 의미에서,와 같은 URL이 있어야하며 [host name]\[user name]\session'DELETE'는 로그 아웃 작업에 올바른 동사가됩니다.

[host name]\bla bla\logout실제로 REST 풀 웨이 (IMO)가 아닌 URL로 사용 하는 이유는 무엇입니까? GET / POST의 올바른 사용법에 대해 토론 해야하는 이유는 무엇입니까?

물론, 나는 또한 내 응용 프로그램에서 로그 아웃 URL에 GET을 사용합니다 :-)


2
이 경우, 사용자가 항상 자신의 세션 에서 로그 아웃 (즉, DELETE) 하기 때문에 URL에 [user name] 부분을 갖는 것은 불필요 해 보인다고 주장합니다 . 절대 다른 사용자 ':-)
Daniel Liuzzi

1
실제로는 아닙니다. 세션이 리소스라고 말하고 삭제하려고합니다. 따라서 모든 세션을 균일하게 처리하려면 URL의 일부로 사용자 이름이 있어야합니다. 당신의 주장은 [사진 갤러리] \ pictures에 PUT 동작을하는 것은 사진에 추가한다는 것을 의미합니다 ([사진 갤러리] \ [사용자 이름] \ pictures에 있음). 다른 자원은 명시 적으로 다루어 져야하며, 암시 적으로 존재할 수 없습니다. 이 사이트는 다른 사용자가 갤러리에 사진을 추가하도록 허용 할 수 있습니다. 다른 사용자가 세션을 죽일 수있는 수퍼 유저가있는 것처럼 액세스 제어의 일부가 될 수 있습니다.
VinayC

1
철학적으로 말하면, 당신은 세션과 사진을 '자원'이라고 부를 수는 있지만, 사실 나는 그것들을 동일하게 취급하지 않을 것입니다. 세션은 항상 본질적으로 현재 사용자 (따라서 세션 이름)로 제한되며 적어도 ASP.NET에서는 다른 사용자의 세션에 액세스 할 수있는 방법이 없습니다. 응용 프로그램 개발자조차도 모든 활성 세션을 열거하거나 세션을 개별적으로 종료 할 수있는 방법이 없습니다. 모든 세션 (InProc)을 종료하기 위해 응용 프로그램을 다시 시작할 수는 있지만 해당 액세스 제어를 호출하지는 않습니다. URL을 제쳐두고도 여전히 GET 또는 POST?
Daniel Liuzzi

리소스 (따라서 주소)는 REST의 중요한 부분입니다. 따라서 내가 말한대로 URL을 선택하면 DELETE가 올바른 단어가됩니다-GET 또는 POST가 아닙니다. 또한 ASP.NET으로 제한하더라도 세션을 열거하고 필요한 경우 다른 세션을 종료 할 수있는 사용자 지정 상태 공급자를 항상 보유 할 수 있습니다. 즉시 사용 가능한 세션의 경우 global.asax의 일부 기능을 통해 기능을 제공 할 수 있습니다. 실제로 그러한 기능이 필요한지 아닌지에 대한 질문입니다. 드문 경우에 사람들은 웹 사이트를 다시 시작하여 사람들을 사이트 밖으로 쫓아내는 경향이 있습니다.
VinayC

이것은 나에게 가장 의미가 있습니다. 웹 API에 세션 경로를 지정하고 DELETE를 호출하십시오. ../session 또는 ../session/current가되어야합니다. ThankVi @VinayC
Simon Hooper

16

로그 아웃하면 응용 프로그램 자체에는 아무런 영향이 없습니다. 응용 프로그램과 관련하여 사용자의 상태를 변경합니다. 이 경우 질문은 사용자로부터 명령을 시작하여이 작업을 시작하는 방법에 따라 결정됩니다. 이는 "파괴적인 조치"가 아니므로 세션이 중단되거나 삭제되었지만 응용 프로그램이나 데이터가 변경되지 않았으므로 두 방법으로 로그 아웃 절차를 시작할 수 없습니다. 이 게시물은 사용자가 시작한 모든 작업 (예 : 사용자가 "로그 아웃"을 클릭 함)에 의해 사용되어야하지만 응용 프로그램이 시작한 로그 아웃을 위해 예약 될 수 있습니다 (예 : 잠재적 인 사용자 침입을 감지 한 예외는 로그 아웃 GET을 사용하여 로그인 페이지로 강제로 리디렉션 됨) ).


흥미있는; 나는 이런 식으로 생각하지 않았다. +1.
Strager

아마도 응용 프로그램 (일부 "캐스 케이 딩 삭제"동작)에 따라 달라질 수 있지만 옳습니다.
Andres Jaan Tack

@JoelEtherton Joel에게 감사합니다. 올바른 답변을 얻을 수있을 때 궁금한 답변을 읽고있었습니다. :)
Kirill Fuchs

4
로그 아웃 상태가 변경되어 혼동됩니다. POST는 상태 변경을위한 동사입니다. GET은 상태 비 저장 데이터를 가져 오기위한 것입니다. POST 요청에 페이로드가있을 것으로 예상하기 때문에 혼란 스럽습니다. 아래에 언급 한 것처럼 DELETE는 세션 개체에서 가장 정확합니다.
Michael Cole

1
@MichaelCole : POST와 GET 사이의 난이도에 동의합니다. 그래도 DELETE 동사의 사용법에 동의하지 않습니다. DELETE는 리소스를 처리하기위한 것이며 세션은 이러한 의미에서 리소스가 아닙니다. 삭제 할 수 있으면 붙여 넣을 수도 있습니다.
Joel Etherton

16

내 관점에서 안녕하세요, 로그인 할 때 사용자 이름 / 비밀번호를 확인하고 일치하는 경우 로그인 토큰을 만듭니다.

CREAT 토큰 => 메소드 POST

로그 아웃 할 때 가장 논리적 인 방법은 DELETE 여야합니다.

DELETE 토큰 => 메소드 DELETE


4
재미있는 각도.
Drumbeg

1
Spring Boot REST 응용 프로그램에서 해당 방법을 사용합니다.
Please_Dont_Bully_Me_SO_Lords

1
의미 적으로 맞습니다. 동의합니다 ...
DAG

1

사전 캐싱 시나리오는 흥미로운 시나리오입니다. 그러나 나는 많은 사이트가 너무 걱정하지 않는다면 아마 당신도 그렇게해서는 안된다고 생각합니다.

아니면 링크가 자바 스크립트로 구현 될 수 있습니까?

편집 : 내가 이해하는 것처럼 기술적으로 GET은 응용 프로그램 상태를 변경하지 않는 읽기 전용 요청이어야합니다. POST는 상태를 변경하는 쓰기 / 편집 요청을위한 것이어야합니다. 그러나 다른 응용 프로그램 문제는 일부 상태 변경 요청에 대해 POST보다 GET을 선호 할 수 있으며 이것에 아무런 문제가 없다고 생각합니다.


감사. DB의 상태는 변경되지 않을 것이다,하지만, 세션 상태는 것. 내가 볼 수있는 유일한 문제는 사용자가 쫓겨 나가는 것에 대해 질문에서 언급 한 것입니다. 비파괴 적이지만 다소 성가시다. 나는 보통 "큰 녀석들이 그렇게한다면 괜찮을 것이다"라는 진언으로 지나간다. 나는 단지 다른 사람들이 이것에 대한 의견을 알고 싶었습니다.
Daniel Liuzzi

0

웹 애플리케이션이 로그 아웃 스크립트를 통해 세션을 포기하게하는 경우 일반적으로 필요하지 않습니다. 일반적으로 포기하려는 세션에 고유 한 세션 변수가 있습니다.


"로그 아웃 스크립트"를 자세히 설명해 주시겠습니까? 쿠키 만료 설정 (사용자가 수동으로 로그 아웃 할 수있는 방법이 필요하지 않음)을 참조하는지 잘 모르겠습니다.
Daniel Liuzzi

로그 아웃 스크립트는 호출하는 사용자 (실제로는 브라우저)의 세션을 종료합니다. ASP.net에서 세션은 버릴 수있는 서버 측 개체입니다. PHP는 비슷한 시스템을 가지고 있습니다. 해당 브라우저는 세션을 종료하는 스크립트를 호출하기 때문에 종료 할 스크립트를 이미 알고 있으므로 POST 또는 GET 변수가 필요하지 않습니다.
Rob

1
네, 지금 드리겠습니다 이미 스크립트, 특히 FormsAuthentication.SignOut ()을 가지고 있지만 GET 또는 POST와 같이 스크립트를 호출하는 방법 에 대한 질문입니다 .
Daniel Liuzzi

오, 당신은 양식에 URL이 있습니까? 정보를 전달하지 않더라도 중요하지 않습니다. 일어날 수있는 최악의 상황은 누군가가 수동으로 스크립트를 열고 로그 아웃하는 것입니다. 필요하지 않은 경우 양식 필드로 만들지 않아도 스크립트에 대한 링크도 작동합니다. 스크립트에 정보를 보내면 POST를 원할 것입니다 (페이지 소스를 보지 않는 한) 사용자에게 정보를 표시하지 않기 때문에 새로 고치면 브라우저에서 경고가 표시됩니다 (페이지 만료), 바람직 할 수 있습니다.
Rob

0

최근에 GET을 사용하여 로그 아웃하는 프로젝트를 진행 중입니다. Nodejs Express의 코드는 다음과 같습니다.

router.js

const express = require("express");
router.get("/signout", signout);

당신의 controller.js

exports.signout  = (req, res) => {
        res.clearCookie('t'); //clearing cookie, which is 
            //assign to the user during sign in.          
            res.json({message : 'Signout success'});   
        };

-2

로그 아웃 (사용자 권한 상승)이 어떻게 해로운 행동인지 알 수 없습니다. "로그 아웃"작업은 이미 로그인 한 사용자 만 사용할 수 있기 때문에 사용하지 않을 수 있습니다.

브라우저 쿠키에 포함 된 무작위로 생성 된 문자열은 모두 사용자 세션을 나타냅니다. 효과적으로 로그 아웃하는 방법은 방문자에게 서비스 일뿐입니다.


2
wget개인 위키에 올바른 세션 쿠키가있는 스파이더 모드에서는 실제로 한 번만 수행해야했습니다. 물론 처음 크롤링 된 URL 중 하나는 /logout입니다.
Helgi

5
가는 시도 SuperLogout.com 에 요청하는 방법을 파괴 GET 볼 /logout페이지를 정말. 예를 들어 Gmail에 다시 로그인하고 채팅에 다시 로그인 한 후 스크롤 한 행 아웃 대화에서 내 장소를 찾아야합니다. 이는 Google.com에만 해당됩니다.
Dan Dascalescu
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.