이것을 이해하도록 도와 줄 수 있습니까? “일반적인 REST 실수 : 세션은 관련이 없습니다”


159

면책 조항 : 저는 REST 생각 학교에 익숙하지 않아서 내 마음을 감싸려고합니다.

그래서 저는이 페이지 인 Common REST Mistakes를 읽고 있으며 세션과 관련이없는 섹션에서 완전히 당황한 것을 발견했습니다. 이것은 페이지가 말하는 것입니다 :

클라이언트가 "로그인"하거나 "연결을 시작할 필요"가 없어야합니다. 모든 메시지에서 HTTP 인증이 자동으로 수행됩니다. 클라이언트 응용 프로그램은 서비스가 아닌 리소스 소비자입니다. 따라서 로그인 할 것이 없습니다! REST 웹 서비스로 항공편을 예약한다고 가정 해 보겠습니다. 서비스에 대한 "세션"연결을 새로 만들지 않습니다. 대신 "일정 생성자 개체"에 새 일정을 만들도록 요청하십시오. 블랭크를 채우기 시작한 다음 웹의 다른 곳에서 완전히 다른 구성 요소를 가져와 다른 블랭크를 채울 수 있습니다. 세션이 없으므로 클라이언트간에 세션 상태를 마이그레이션하는 데 문제가 없습니다. "세션 선호도"문제도 없습니다

좋아, 모든 메시지에서 HTTP 인증이 자동으로 수행된다는 것을 알지만 어떻게? 모든 요청과 함께 사용자 이름 / 암호가 전송됩니까? 그것은 단지 공격 표면적을 증가시키지 않습니까? 퍼즐의 일부가 빠진 것 같습니다.

예를 들어 /sessionGET 요청을 수락하여 요청의 일부로 사용자 이름 / 암호를 전달하고 인증에 성공하면 세션 토큰을 반환 하는 REST 서비스를 갖는 것이 좋지 않습니까? 후속 요청과 함께 전달 되었습니까? REST 관점에서 의미가 있습니까, 아니면 요점이 누락 되었습니까?


모든 요청은 항상 인증되며 세션 하이재킹은 중요합니다. 편안한 것은 이것을 더 명백하게하지만 더 많이 노출 시키지는 않습니다.
Jasen

답변:


79

RESTful이 되려면 각 HTTP 요청은 수신자가 HTTP의 상태 비 저장 특성과 완전히 조화되도록 처리하기 위해 충분한 정보를 자체적으로 가져와야합니다.

좋아, 모든 메시지에서 HTTP 인증이 자동으로 수행된다는 것을 알지만 어떻게?

예, 사용자 이름과 비밀번호는 모든 요청과 함께 전송됩니다. 그렇게하는 일반적인 방법은 기본 액세스 인증다이제스트 액세스 인증 입니다. 예, 도청자가 사용자의 자격 증명을 캡처 할 수 있습니다. 따라서 TLS (Transport Layer Security)를 사용하여 보내고받는 모든 데이터를 암호화합니다 .

요청의 일부로 사용자 이름 / 암호를 전달하고 인증에 성공하면 세션 토큰을 반환하는 GET 요청을 수락하는 REST 서비스가 / session과 같이 좋지 않을 수 있습니다. 그런 다음 후속 요청과 함께 전달됩니까? REST 관점에서 의미가 있습니까, 아니면 요점이 누락 되었습니까?

이되지 않을 것 편안하고을 은 상태 수행하지만, 그러나 그것은 사용자의 편의를 이후 매우 일반적이기 때문에, 사용자는 매번 로그인 할 필요가 없습니다.

"세션 토큰"에서 설명하는 것을 일반적으로 로그인 쿠키 라고합니다 . 예를 들어 Yahoo! 계정에는 "2 주 동안 로그인 상태 유지"라는 확인란이 있습니다. 이것은 본질적으로 "내가 성공적으로 로그인하면 2 주 동안 세션 토큰을 유지하십시오"라고 말합니다. 웹 브라우저는 요청하는 각 HTTP 요청과 함께 이러한 로그인 쿠키 (및 기타)를 보냅니다.


5
이 대답은 나에게 이해가되지 않습니다. 첫째, 매번 로그인과 암호를 전달해도되므로 한 번도 괜찮습니다. 그런 다음, 토큰 형태의 성공적인 로그인 상태를 클라이언트에게 반환하려는 아이디어가 제안됩니다. 필요한 경우 토큰은 생성 시간을 인코딩 할 수 있습니다. 우리는 확실히 고객에게 정보를 반환 할 수 있습니다. 따라서이 제안은 나에게 잘 보입니다. 대답은 "상태를 전달"하기 때문에 문제가 없지만 "REST"의 "ST"는 클라이언트와 서버간에 상태를 전송할 수 있다는 생각이 아닌가?

33

REST 서비스가 모든 HTTP 요청에 대해 인증을 요구하는 것은 드문 일이 아닙니다. 예를 들어 Amazon S3에서는 모든 요청에 ​​사용자 자격 증명, 정확한 수행 요청 및 현재 시간에서 파생 된 서명이 있어야합니다. 이 서명은 클라이언트 측에서 계산하기 쉽고 서버에서 신속하게 확인할 수 있으며 현재 시간을 기준으로하므로이를 가로채는 공격자에게 제한적으로 사용됩니다.


3
+1 정교하게 설명해 주실 수 있습니까 : 현재 시간을 기준으로하므로이를 가로채는 공격자가 제한적으로 사용하고 있습니까? 암호화 된 사용자 이름과 비밀번호가 포함 된 쿠키에 대해 이야기하고 있지 않습니까? SO처럼? (IMHO)
Royi Namir

2
@RoyiNamir : 쿠키에 대해 이야기하고 있지 않습니다. S3에서 사용하는 서명은 HTTP 요청에 대한 매개 변수이지만 쿠키 는 아니며 모든 요청에 ​​대해 다시 계산됩니다.
Greg Hewgill

따라서 사용자에 대한 정보를 저장해야하는 경우 어디에 저장합니까? db에서? DB에 각 요청을 가고 싶지 않습니다 .... 그리고 여전히 휴식을 사용하고 싶습니다 .... 도와 줄 수 있습니까?
Royi Namir

@RoyiNamir : 목표를 달성하는 방법에 대한 특정 질문이 있으면 새로운 질문을하십시오 . 의견에 추가 질문에 대한 답변을 드릴 수 없습니다.
Greg Hewgill

10

많은 사람들이 REST 프린시 펄을 매우 명확하게 이해하지 못합니다. 세션 토큰을 사용한다고해서 항상 상태를 유지할 수있는 것은 아니며, 각 요청과 함께 사용자 이름 / 암호를 보내는 이유는 인증 전용이며 토큰을 보내는 것과 동일합니다 (로그인으로 생성됨) process) 클라이언트에게 데이터를 요청할 권한이 있는지 여부를 결정하기 위해 사용자 이름 / 암호 또는 세션 토큰을 사용하여 표시 할 데이터를 결정할 때 REST 경의를 위반합니다! 대신에 데이터를 표시하거나 표시하지 않기 위해 혐의를 위해서만 사용해야합니다.

귀하의 경우에는 YES라고 말하면 RESTy이지만 REST API에서 기본 PHP 세션을 사용하지 말고 정해진 시간 내에 만료되는 자체 해시 토큰을 생성하십시오!


1
감사합니다. 왜 네이티브 PHP 세션을 피하고 대신 자체 해시 토큰을 사용해야합니까?
Matthew

더 많은 보안과 통제력을 위해 내가 말한 훌륭한 이유가 아닙니다.
EvilThinker

이것은 받아 들인 대답보다 낫습니다. 적어도 제안은 RESTy로 받아들입니다. 그러나 전달 된 정보를 사용하여 사용자 종속 권한 부여를 수행 할 수없는 이유는 알 수 없습니다. 일부 사용자는 일부 데이터에 액세스 할 수 있지만 그렇지 않은 사용자도 있습니다. 프로토콜이 RESTful하지는 않습니다.

8

아니요, 요점을 놓치지 않습니다. Google의 ClientLogin 은 클라이언트가 HTTP 401 응답을 사용하여 "/ session"으로 이동하라는 지시를받는 경우를 제외하고는 정확하게이 방식으로 작동합니다. 그러나 이것은 세션을 생성하지 않으며 클라이언트가 자격 증명을 통과하지 않고 (일시적으로) 자신을 인증 할 수있는 방법을 만들고 서버 가이 임시 자격 증명의 유효성을 적절하게 제어 할 수있게합니다.


11
@ unforgiven3 반환 된 토큰이 사용자를 인증하는 데만 사용되고 서버가 사용자를 서버에 저장된 다른 상태에 연결하는 데 사용하지 않는 한 REST 제약 조건이 위반되는 것을 볼 수 없습니다.
대럴 밀러

4
@ unforgiven3 서버에서 반환 된 토큰은 실제로 사용자가 자신이 누구인지를 증명합니다. 따라서 사용자 이름과 비밀번호를 포함한 각 요청 대신, 각 요청에는 서버의 정확성을 확신 할 수있는 방식으로 구성된 토큰이 포함됩니다.
Darrel Miller

1
@ unforgiven3, 대럴이 맞습니다. 반향 된 토큰은 토큰이 만료 될 때까지 기본 다이제스트 인증과 마찬가지로 모든 HTTP 요청에서 클라이언트가 전송해야합니다. 이 경우 클라이언트는 로그인을 반복하여 선택적으로 사용자에게 자격 증명을 요구하는 등의 작업을 수행 할 수 있습니다. 원한다면 답을 정교하게 만들 수 있습니다. 편집 : (그리고 오래된 질문에 대한 답변을 유지 주셔서 감사합니다!)
mogsie

1
문제없이, mogsie, 항상 이러한 유형의 것들에 대해 이야기하는 것이 흥미 롭습니다. 각 HTTP 요청에서 토큰이 어떻게 다시 전송되는지 이해하지만 구현 세부 사항 인 것 같습니다. 그러나 이제이 방법이 REST 원칙을 위반하지 않는 이유를 알았습니다. 답변 주셔서 감사합니다!
Rob

6
@ unforgiven3, 도움이 될 수 있습니다 : 토큰은 서명 된 정보입니다. 자 급식입니다. 서버는 이전에 저장된 상태를 확인하지 않고 토큰의 유효성을 검사 할 수 있습니다. 따라서 클라이언트에 저장되어 앞뒤로 전송되는 상태 일뿐입니다.
Iravanchi

5

좋아, 모든 메시지에서 HTTP 인증이 자동으로 수행된다는 것을 알지만 어떻게?

"인증 :"클라이언트가 HTTP 헤더를 보냅니다. 기본 (일반 텍스트) 또는 요약입니다.

요청의 일부로 사용자 이름 / 암호를 전달하고 인증에 성공하면 세션 토큰을 반환하는 GET 요청을 수락하는 REST 서비스가 / session과 같이 좋지 않을 수 있습니다. 그런 다음 후속 요청과 함께 전달됩니까? REST 관점에서 의미가 있습니까, 아니면 요점이 누락 되었습니까?

세션의 전체 아이디어는 서버 측의 상태를 유지함으로써 상태 비 저장 프로토콜 (HTTP) 및 벙어리 클라이언트 (웹 브라우저)를 사용하여 상태 기반 애플리케이션 을 만드는 것 입니다. REST 원칙 중 하나는 "하이퍼 미디어 링크에서 사용하기위한 범용 구문을 사용하여 모든 자원을 고유하게 처리 할 수 ​​있음" 입니다. 세션 변수는 URI를 통해 액세스 할 수없는 것입니다. 진정으로 RESTful 응용 프로그램은 클라이언트 측에서 상태를 유지하여 HTTP로, 바람직하게는 URI로 필요한 모든 변수를 보냅니다.

예 : 페이지 매김으로 검색 양식에 URL이 있습니다.

http://server/search/urlencoded-search-terms/page_num

북마크 가능한 URL과 공통점이 많습니다.


4
인증 정보는 URI를 통해서도 액세스 할 수 없습니다. 모두가 요청 헤더의 일부로 인증 정보를 보내는 것에 대해 이야기하고 있습니다. 요청에 세션 토큰을 포함시키는 것과 어떻게 다릅니 까? URI에서 세션 토큰을 사용하는 것이 아니라 요청에 전달 된 데이터에서 사용한다고 말하고 있습니다.
Rob

인증은 해당 작업을 실행할 권한이 있는지 확인하며 RESTful 응용 프로그램에서는 결과에 영향을 미치지 않습니다.
vartec

4
해당 작업을 실행할 권한이 있는지 세션 토큰도 설정합니다. 결과에 영향을 미치지 않는다는 것은 무엇을 의미합니까? 발신자가 인증되지 않은 경우 승인되지 않은 오류가 발생합니다. 세션 토큰도 마찬가지입니다. 정말 차이가 보이지 않습니까?
Rob

3
아니요, 세션 토큰은 서버에 저장된 상태를 처리하는 핸들 입니다. 그것은 단지 RESTful하지 않습니다. Not Authorized에 관해서는 그 결과를 알 수 없습니다. 오히려 try / catch에서와 같이 예외를 고려하고 싶습니다.
vartec

충분히 공정한, vartec-말이됩니다. 후속 감사합니다!
Rob

3

클라이언트 세션 수명 시간을 제어하려면 제안이 괜찮다고 생각합니다. RESTful 아키텍처를 사용하면 상태 비 저장 응용 프로그램을 개발할 수 있다고 생각합니다. @ 2pence는 "각 HTTP 요청은 수신자가 HTTP의 무국적 속성과 완전히 조화되도록 처리하기 위해 충분한 정보를 자체적으로 가져와야한다 " 고 썼다 .

그러나 항상 그런 것은 아니며 때때로 응용 프로그램에서 클라이언트 로그인 또는 로그 아웃시기를 알려주고이 정보를 기반으로 잠금 또는 라이센스와 같은 리소스를 유지 관리해야합니다. 그러한 경우의 예를 보려면 내 후속 질문 을 참조하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.