REST 애플리케이션이 상태 비 저장 상태 인 경우 세션을 어떻게 관리합니까?


536

설명이 필요합니다. REST에 대해 읽고 RESTful 응용 프로그램을 작성했습니다. Wikipedia에 따르면 REST 자체는 Representational State Transfer로 정의됩니다 . 그러므로 나는 모든 사람들이 계속 뿜어내는 이 무국적 gobbledeygook 을 이해하지 못합니다 .

위키 백과에서 :

특정 시점에서 클라이언트는 응용 프로그램 상태간에 전환되거나 "휴면"상태 일 수 있습니다. 휴면 상태의 클라이언트는 사용자와 상호 작용할 수 있지만 서버 집합이나 네트워크에서로드를 생성하지 않고 클라이언트 별 저장소를 사용하지 않습니다.

그들은 단지 세션 / 응용 프로그램 수준의 데이터 저장소를 사용하지 않는다고 말하고 있습니까?

REST의 한 가지 목표는 예를 들어 게시물 내에 페이징 요청을 숨기고 요청의 페이지 번호를 GET URI의 일부로 만드는 대신 URI 액세스를 일관성 있고 사용 가능하게 만드는 것입니다. 이해가 되네요 그러나 클라이언트 당 데이터 (세션 데이터)를 서버 측에 저장해서는 안된다고 말하는 것은 선상으로 진행되는 것처럼 보입니다 .

메시지 대기열이 있는데 사용자가 메시지를 읽으려고했지만 메시지를 읽을 때 세션 기간 동안 특정 발신자 메시지가 들어오는 것을 차단하려면 어떻게해야합니까? 이것을 서버 쪽의 장소에 저장하고 서버가 사용자가 차단하지 않은 메시지 (또는 메시지 ID) 만 보내도록하는 것이 합리적이지 않습니까?

새 메시지 목록을 요청할 때마다 차단하기 위해 전체 메시지 보낸 사람 목록을 보내야합니까? 나에게 관련된 메시지 목록은 처음에는 공개적으로 이용 가능한 리소스가 아니어야합니다.

다시 한 번 이해하려고 노력했습니다. 누군가가 제발 명확히.


최신 정보:

나는 거기까지 모든 것을 얻지 못하는 대답이있는 스택 오버플로 질문을 발견했다 : REST에서 상태를 관리하는 방법 중요한 클라이언트 상태가 모든 요청마다 전송 되어야 한다고 말하는 방법 . .. 많은 오버 헤드가있는 것 같습니다 ... 맞습니까?


2
@ S.Lott : 의도적으로 오도 된 것으로 생각하지 않습니다. 혼란스러운 용어 때문에 오해라고 생각합니다.
저의 정확한 의견 그냥

2
@ 나의 올바른 의견을 생각하십시오 : 재미있는 추측. "무 상태"는 REST 프로토콜 자체가 무 상태임을 의미한다는 점에서 명백하기 때문에 나는 그런 것을 믿을 수 없었다. 기본 응용 프로그램 상태와 PUT, POST 및 DELETE 요청으로 업데이트하지 않습니다.
S.Lott

@ S.Lott : HTTP 프로토콜 자체는 상태 비 저장입니다. 아래에서 논의한 내용에서 REST는 웹 서버가 세션 상태를 처리하지 않고 (DB와 같은 다른 종류의 상태와 달리) 앱을 빌드하는 방법에 대한 관점입니다. 난 REST는 생각하지 않았다 이었다 프로토콜, 오히려 HTTP 프로토콜을 사용하는 방법에 볼 수 있습니다. 나는 클라이언트 측이 모든 클라이언트 특정 세션 데이터를 저장하고 URI 액세스를 가능한 한 dem 등하 지 않게하여 확장 할 수 있도록 응용 프로그램을 빌드하는 방법에 관한 것이라고 생각한다고 생각 했습니다. 아마도 ... :(
Zak

1
"아마 .."그게 무슨 뜻입니까? 새로운 질문이 있습니까? SO를 자유롭게 검색하십시오. 여기에 존재하지 않으면 요청하십시오.
S.Lott

실제로 Webber, Parastatidis 및 Robinson의 ReST를 읽은 사람이 있습니까? 아래 답변은 의미가 있지만 restbucks 예제의 커피 주문은 고객에 대한 상태입니까? 주문의 수는 클라이언트의 수에 따라 확장 할 수 있습니다. 클라이언트 상태와 리소스 사이의 경계는 어디에 있습니까?
Rikki

답변:


340

상태 비 저장은 모든 HTTP 요청이 완전히 격리됨을 의미합니다. 클라이언트가 HTTP 요청을하면 서버가 해당 요청을 수행하는 데 필요한 모든 정보가 포함됩니다. 서버는 이전 요청의 정보에 의존하지 않습니다. 해당 정보가 중요하면 클라이언트는 후속 요청에서 다시 보내야합니다. 상태 비 저장은 또한 새로운 기능을 제공합니다. 로드 밸런싱 된 서버에 상태 비 저장 응용 프로그램을보다 쉽게 ​​배포 할 수 있습니다. 상태 비 저장 응용 프로그램은 캐시하기도 쉽습니다.

실제로 두 종류의 상태가 있습니다. 클라이언트에있는 응용 프로그램 상태 및 서버에있는 리소스 상태

웹 서비스는 실제로 요청을 할 때 응용 프로그램 상태 만 신경 써야합니다. 나머지 시간은 당신이 존재한다는 것을조차 알지 못합니다. 이는 클라이언트가 요청을 할 때마다 서버가 처리해야하는 모든 응용 프로그램 상태를 포함해야한다는 것을 의미합니다.

자원 상태는 모든 클라이언트에 대해 동일하며 서버의 올바른 위치입니다. 서버에 사진을 업로드하면 새 리소스가 만들어집니다. 새 사진에는 고유 한 URI가 있으며 향후 요청의 대상이 될 수 있습니다. HTTP를 통해이 리소스를 가져오고 수정하고 삭제할 수 있습니다.

이것이 무국적 상태와 다양한 상태의 의미를 차별화하는 데 도움이되기를 바랍니다.


4
이것은 요청이 전송 될 때마다 클라이언트가 인증을 위해 사용자 / 암호를 보내야한다는 것을 의미합니까? 세션을 모든 서버간에 공유 SQL이 아닌 db에 있더라도 세션을 저장하지 않는 것이 stateless가 아니거나 그렇지 않은 것입니까?
Carlos Navarro Astiasarán

1
@ CarlosNavarroAstiasarán에는 상태 비 저장 인증을 처리하기위한 다양한 기술이 있습니다. 예를 들어 Google JWT
geoidesic

1
@geoidesic : "JSON 웹 토큰은 상태 비 저장이므로 서버 상태를 저장하지 않고 무효화 할 수있는 방법이 없으므로 상태 비 저장 토큰의 이점을 무효화합니다." Wikipedia
ulatekh

@ulatekh 그것은 당신이 토큰으로 할 수있는 일에 대한 심한 오해입니다. 승인 된 ID를 토큰과 함께 저장하고 승인 된 ID를 주장으로하는 토큰 만 허용하는 것은 매우 간단합니다. Stateless는 데이터베이스에서 무언가를 할 수 없다는 것을 의미하지는 않습니다. 기본적으로 토큰의 동일한 ID와 일치해야하는 ID를 데이터베이스에 저장합니다. 토큰을 취소하려면 데이터베이스에서 ID를 제거하십시오. 서비스 자체에는 상태가 기억되지 않습니다. 또는 데이터베이스의 사용자와 함께 서명 키를 저장하고 키를 취소하는 것이 더 좋습니다.
앤드류 T 피넬

@AndrewTFinnell : 승인 된 ID를 서버에 저장해야하는 경우 REST 로그인을 처리 할 수있는 잠재적 인 모든 서버에 저장해야합니다.이 서버는 대규모 병렬 웹 서버 아키텍처에서 많은 서버 상태를 포함 할 수 있습니다.
ulatekh

491

기본 설명은 다음과 같습니다.

서버에 클라이언트 세션 상태가 없습니다.

상태 비 저장은 서버클라이언트 세션 에 대한 상태를 서버 측에 저장하지 않음을 의미합니다 .

클라이언트 세션은 클라이언트에 저장됩니다. 서버는 모든 서버가 언제든지 클라이언트를 서비스 할 수있는 무 수단입니다, 더이없는 세션 유사성 또는 지속적인 세션 . 관련 세션 정보는 클라이언트에 저장되고 필요에 따라 서버로 전달됩니다.

이는 웹 서버가 대화하는 다른 서비스가 클라이언트의 현재 응용 프로그램 / 세션 상태가 아니라 쇼핑 카트와 같은 비즈니스 객체에 대한 상태를 유지하는 것을 방해하지 않습니다.

클라이언트의 응용 프로그램 상태는 서버에 저장되지 않지만로부터 건네 줄 수가 안 클라이언트 를 필요로 모든 장소에.

이것이 바로 STRESTState Transfer라는 곳 입니다. 서버가 저장하지 않고 상태를 전달합니다. 이것이 수백만 명의 동시 사용자로 확장 할 수있는 유일한 방법입니다. 수백만 개의 세션이 수백만 개의 세션이기 때문에 다른 이유가 없다면.

세션 관리로드는 모든 클라이언트에서 상각되며 클라이언트는 세션 상태를 저장하며 서버는 상태가없는 방식으로 많은 규모의 클라이언트를 서비스 할 수 있습니다.

수만 명의 동시 사용자 에게만 필요한 서비스라고해도 서비스를 무 상태로 만들어야합니다. 수만 명은 여전히 ​​수만 명이며 그에 따른 시간과 공간 비용이 있습니다.

상태 비 저장 (stateless)은 HTTP 프로토콜과 웹이 일반적으로 작동하도록 설계된 방식이며 전체적으로 더 간단한 구현이며 많은 세션 상태를 유지하기 위해 서버 측 로직 대신 단일 코드 경로를 갖습니다.

매우 기본적인 구현 원칙이 있습니다.

이들은 구현이 아닌 원칙이므로 이러한 원칙을 충족시키는 방법은 다를 수 있습니다.

요약하면 5 가지 주요 원칙 은 다음과 같습니다.

  1. 모든“사물”에 ID를 부여하십시오
  2. 서로 연결
  3. 표준 방법 사용
  4. 여러 표현이 포함 된 리소스
  5. 무국적 통신

REST 논문 의 인증 또는 권한 부여에 대해서는 아무것도 없습니다 .

그렇지 않은 요청과 RESTful 한 요청을 인증하는 것 외에 다른 것은 없기 때문입니다. 인증은 RESTful 토론과 관련이 없습니다.

특정 요구 사항에 대한 상태 비 저장 응용 프로그램을 만드는 방법을 설명하는 것은 너무 복잡 합니다.

REST와 관련하여 인증 및 권한 부여를 구현하는 것은 훨씬 더 광범위 하며 구현에 대한 다양한 접근 방식은 일반적으로 인터넷에서 자세히 설명됩니다.

이에 대한 도움말 / 정보를 요청하는 의견은 더 이상 필요하지 않음 으로 표시되어야합니다 .


22
그것은 수백만 명의 사용자로 확장 할 수 있는 유일한 방법 이라는 꽤 대담한 진술처럼 보입니다 . 서버 측 세션이 다른 서비스 일 수없는 이유는 무엇입니까?
Zak

27
@Zak : 수백만 개의 세션이 수백만 개의 세션이기 때문에. 요점은이 모든 세션 관리의 오버 헤드를 피하는 것입니다.
S.Lott

91
대담한 경험이 아닙니다

21
내 답변에는 모든 요청에 ​​대한 데이터베이스 액세스를 기반으로 한 솔루션을 의미하지 않습니다. 그렇다고 생각하면 해당 규모의 인증 및 권한 부여를 이해하지 못하는 것입니다. 인증은 상태에서 암시적일 수 있습니다. 페이스 북이 REST API의 모든 요청에 ​​대해 "데이터베이스 액세스"를 수행한다고 생각하십니까? 아니면 그 문제에 대한 구글? 힌트 : 아니오

6
따라서 분산 캐시에 사용자 상태를 memcache라고 저장하면 모든 웹 서버가 상태를 저장할 필요가 없지만 memcache에서 상태를 가져와야하는 경우이 응용 프로그램을 상태 비 저장으로 간주 할 수 있습니까?
Jaskey

76

그들은 단지 세션 / 응용 프로그램 수준의 데이터 저장소를 사용하지 않는다고 말하고 있습니까?

아닙니다. 그들은 사소한 방식으로 그런 말을하지 않습니다.

그들은 "세션"을 정의하지 않는다고 말합니다. 로그인하지 마십시오. 로그 아웃하지 마십시오. 요청과 함께 자격 증명을 제공하십시오. 각 요청은 독립적입니다.

여전히 데이터 저장소가 있습니다. 여전히 인증 및 권한이 있습니다. 세션을 설정하고 세션 상태를 유지하는 데 시간을 낭비하지 않아도됩니다.

요점은 각 요청 (a)는 완전히 독립적이며 (b) 실제 작업 없이도 거대한 병렬 서버 팜에 간단하게 팜 아웃 될 수 있다는 것입니다. Apache 또는 Squid는 맹목적으로 성공적으로 RESTful 요청을 전달할 수 있습니다.

메시지 대기열이 있는데 사용자가 메시지를 읽으려고했지만 메시지를 읽을 때 세션 기간 동안 특정 발신자 메시지가 들어오는 것을 차단하려면 어떻게해야합니까?

사용자가 필터를 원하면 각 요청에 필터를 제공하십시오.

서버가 사용자에 의해 차단되지 않은 메시지 (또는 메시지 ID) 만 보내도록하는 것이 이치에 맞지 않습니까?

예. RESTful URI 요청에 필터를 제공하십시오.

새 메시지 목록을 요청할 때마다 차단하기 위해 전체 메시지 보낸 사람 목록을 보내야합니까?

예. 이 "차단할 메시지 발신자 목록"은 얼마나 클 수 있습니까? PK의 짧은 목록?

GET 요청은 매우 클 수 있습니다. 필요한 경우, 당신은 쿼리의 종류 같은 소리에도 POST 요청을 시도 할 수 있습니다.


28
"로그인하지 마십시오. 로그 아웃하지 마십시오. 요청과 함께 자격 증명을 제공하십시오." 클라이언트에서 자격 증명을 어디에 / 어떻게 저장해야하는지에 대한 세부 정보없이 REST API에서 상태 비 저장 상태를 유지하는 방법에 대한 질문에는 항상 이와 같은 응답이 표시됩니다. 확실히 우리는 로컬 저장소에 사용자 이름과 암호를 저장해서는 안됩니다!
BeniRose

2
@BeniRose 우리는 사용자를 고유하게 식별 요청에 토큰 것을 로컬 스토리지 및 사용 토큰을 저장할 수 없습니다?
Nikhil Sahu

1
로컬 스토리지는 내가 이해 한 것에서 많은 보안 문제가 있습니다. 또한 토큰 무효화, 사용자 로그 아웃 등과 같은 클라이언트 측 세션과 관련된 다른 문제도 있습니다.
BeniRose

3
서명이있는 JWT를 사용하면 서명 확인이 빠르므로 해당 상태의 유효성을 확인할 수 있습니다.
Archimedes Trajano

36

서버와의 완전한 상태 비 저장 상호 작용을 지원하면 클라이언트에 추가 부담이 발생합니다. 그러나 응용 프로그램의 확장을 고려하면 클라이언트의 계산 능력은 클라이언트 수에 정비례합니다. 따라서 많은 수의 클라이언트로 확장하는 것이 훨씬 더 가능합니다.

특정 클라이언트의 상호 작용과 관련된 일부 정보를 관리하기 위해 서버에 약간의 책임을 두 자마자 서버를 소비하는 부담이 빠르게 커질 수 있습니다.

트레이드 오프입니다.


32

사용자 애플리케이션 상태 관리의 이력보기

전통적인 의미에서 세션은 서버 내부의 응용 프로그램에서 사용자의 상태를 유지합니다. 플로우의 현재 페이지이거나 이전에 입력되었지만 아직 기본 데이터베이스에 유지되지 않은 페이지 일 수 있습니다.

이러한 요구의 이유는 클라이언트 특정 (예 : 브라우저 특정) 응용 프로그램이나 플러그인을 만들지 않고 상태를 효과적으로 유지하기 위해 클라이언트 측에 표준이 없기 때문입니다.

HTML5와 XML 헤더 요청은 시간이 지남 에 따라 서버 사이를 오가지 않고 클라이언트 (예 : 브라우저)에서 애플리케이션 상태 를 포함한 복잡한 데이터를 표준 방식으로 저장하는 개념을 표준화했습니다 .

REST 서비스의 일반적인 사용법

REST 서비스는 일반적으로 수행해야하는 트랜잭션이 있거나 데이터를 검색해야하는 경우에 호출됩니다.

REST 서비스는 최종 사용자가 아닌 클라이언트 측 애플리케이션에서 호출하도록되어 있습니다.

인증 중

서버에 대한 요청의 경우 요청의 일부에 권한 토큰이 포함되어야합니다. 구현 방법은 응용 프로그램에 따라 다르지만 일반적 으로 인증 BASIC또는 CERTIFICATE형식입니다.

REST 서비스에서는 양식 기반 인증을 사용하지 않습니다. 그러나 위에서 언급 한 것처럼 REST 서비스는 사용자가 아니라 애플리케이션이 호출하도록되어 있습니다. 응용 프로그램은 인증 토큰을 얻는 것을 관리해야합니다. 필자의 경우 JASPIC with OAuth 2.0 쿠키 를 사용하여 인증을 위해 Google에 연결하고 자동 테스트를 위해 간단한 HTTP 인증을 사용했습니다. 또한 로컬 테스트에도 JASPIC통한 HTTP 헤더 인증을 사용 했습니다 (SiteMinder에서 동일한 접근 방식을 수행 할 수는 있음).

이러한 예에 따라 인증은 클라이언트 측에서 관리되지만 (SiteMinder 또는 Google은 인증 세션을 끝에 저장하지만) 해당 상태에 대해 수행 할 수있는 작업은 없지만 REST 서비스 응용 프로그램의 일부는 아닙니다.

검색 요청

REST의 검색 요청은 GET특정 자원이 요청되고 캐시 가능한 작업입니다. 요청에는 인증 및 URI와 같이 데이터를 검색하는 데 필요한 모든 것이 있으므로 서버 세션이 필요하지 않습니다.

거래 스크립트

위에서 언급 한 것처럼 클라이언트 측 애플리케이션 자체는 클라이언트 측에서 관리하는 인증과 함께 REST 서비스를 호출합니다.

이것이 REST 서비스에서 [정확하게 수행 된 경우] REST 서버에 단일 요청을 가져 오는 것이 단일 트랜잭션에 필요한 모든 것을 수행하는 단일 사용자 조작에 필요한 모든 것을 포함한다는 것입니다. 트랜잭션 스크립트 는 패턴입니다. 호출됩니다.

이것은 POST일반적으로 요청을 통해 이루어 지지만 이와 같은 다른 것들도 PUT사용될 수 있습니다.

REST (내가 직접 한 것)의 많은 고안된 예는 HTTP 프로토콜에 정의 된 많은 부분을 따르려고 시도했지만, 더 실용적이기로 결정하고 GET 및 POST에만 맡겼습니다 . 이 POST방법은 POST-REDIRECT-GET 패턴을 구현할 필요조차 없습니다.

내가 위에서 언급 한대로에 관계없이하지만, 클라이언트 측 응용 프로그램은 서비스를 호출 하나가 될 것이며, 그것은 단지 호출 POST은 (하지 때마다)에 필요로 할 때 모든 데이터를 요청합니다. 이렇게하면 서버에 대한 지속적인 요청이 방지됩니다.

투표

REST는 폴링에도 사용할 수 있지만 브라우저 호환성으로 인해 사용하지 않는 한 권장하지 않습니다. 이를 위해 API 계약 을 디자인 한 WebSocket을 사용 합니다. 구형 브라우저의 또 다른 대안은 CometD입니다.


27

REST는 매우 추상적입니다. 그것은 좋은, 간단한, 실제 사례를 가지고하는 데 도움이됩니다.

Tumblr, Instagram, Facebook 및 Twitter와 같은 모든 주요 소셜 미디어 앱을 예로 들어 보겠습니다. 그것들은 모두 더 아래로 스크롤할수록 더 많은 내용을 볼 수 있고 시간이 지남에 따라 계속 스크롤되는보기를 갖습니다. 그러나 우리는 당신이 스크롤 한 곳을 잃어 버린 순간을 경험했으며 앱은 다시 맨 위로 돌아갑니다. 앱을 종료 한 다음 다시 열면 다시 상단으로 돌아옵니다.

서버가 세션 상태를 저장하지 않았기 때문입니다. 슬프게도 스크롤 위치가 클라이언트의 RAM에 저장되었습니다.

다행스럽게도 다시 연결할 때 다시 로그인 할 필요는 없지만 클라이언트 측의 저장된 로그인 인증서가 만료되지 않았기 때문입니다. 앱을 삭제하고 다시 설치하면 서버가 IP 주소를 세션과 연결하지 않았으므로 다시 로그인해야합니다.

REST를 준수하기 때문에 서버에 로그인 세션이 없습니다.


위의 예제에는 웹 브라우저가 전혀 포함되어 있지 않지만 백엔드에서는 앱이 HTTPS를 통해 호스트 서버와 통신하고 있습니다. 내 요점은 REST에는 쿠키 및 브라우저 등이 필요하지 않다는 것입니다. 클라이언트 측 세션 상태를 저장하는 다양한 방법이 있습니다.

그러나 웹 브라우저에 대해 잠시 이야기 해 봅시다. 왜냐하면 여기서 아무도 이야기하지 않는 REST의 또 다른 주요 이점이 있기 때문입니다.

서버가 세션 상태를 저장하려고하면 각 개별 클라이언트를 어떻게 식별해야합니까?

많은 사람들이 공유 라우터에서 동일한 주소를 사용할 수 있기 때문에 IP 주소를 사용할 수 없습니다. 그럼 어떻게?

여러 가지 이유로 인해 MAC 주소를 사용할 수 없습니다. 여러 가지 다른 Facebook 계정과 동시에 여러 브라우저와 앱에서 동시에 로그인 할 수 있기 때문입니다. 한 브라우저는 다른 브라우저 인 것처럼 가장 할 수 있으며 MAC 주소는 스푸핑하기 쉽습니다.

서버가 사용자를 식별하기 위해 클라이언트 쪽 상태를 저장해야하는 경우 요청을 처리하는 데 걸리는 시간보다 RAM에 더 오래 저장해야합니다. 그렇지 않으면 해당 데이터를 캐시해야합니다. 서버는 프로세서 속도는 말할 것도없고 RAM과 캐시의 양이 제한되어 있습니다. 서버 측 상태는 세 가지 모두에 기하 급수적으로 추가됩니다. 또한 서버가 세션에 대한 상태를 저장하려는 경우 현재 로그인 한 각 브라우저 및 앱과 사용하는 각 장치마다 별도로 저장해야합니다.


그렇다면 ... REST가 확장성에 왜 중요한지 지금 알기를 바랍니다. 왜 서버 측 세션 상태가 용접 가속 앤빌이 자동차 가속에 해당하는지 서버 확장성에 대한 이유를 알 수 있기를 바랍니다.


사람들이 혼란스러워하는 곳은 "상태"는 데이터베이스에 저장된 정보를 의미한다고 생각하는 것입니다. 아니요, 서버를 사용할 때 서버의 RAM에 있어야하는 정보를 말합니다.


13

여기서 기본적인 문제는 SessionState를 혼합하는 것 입니다. REST 는 서버에 상태 를 저장해서는 안된다고 지정하지만 사용자 세션 을 저장하는 것을 막는 것은 없습니다 .

서버 에서 상태 를 관리 한다는 것은 서버가 클라이언트가 수행하는 작업 (응용 프로그램의 어느 섹션에서 어떤 페이지를보고 있는지)을 정확히 알고 있음을 의미합니다. 그리고 이것은 당신이 할 필요가없는 것입니다.

세션 스토리지를 최소 크기로 유지해야한다는 다른 사람들의 의견에 동의합니다. 이는 상식이지만 실제로 응용 프로그램에 따라 다릅니다. 즉, 캐시 된 데이터로 세션을 유지하여 서버에 적은 부하로 요청을 처리하고 클라이언트가 사용할 임시 인증 / 액세스 토큰을 제공하여 인증을 관리 할 수 ​​있습니다. 세션 / 토큰이 만료 될 때마다 새로운 세션 / 토큰을 생성하고 클라이언트에게 사용하도록 요청하십시오.

누군가는 클라이언트가 토큰을 더 잘 생성해야한다고 주장 할 수 있습니다. 두 가지 방식으로 작동하며 응용 프로그램과 API를 사용하는 사람에 따라 다릅니다.

또한 민감한 세션 데이터를 서버에 유지하는 것이 올바른 방법입니다. 예를 들어, "isFreeGift"라는 필드가 포함 된 장바구니를 고객이 보관하도록 클라이언트를 신뢰할 수 없습니다. 이러한 정보는 서버에 보관해야합니다.

그의 답변 에 Santanu Dey 가 제공 한 비디오 링크 가 도움이됩니다. 당신이하지 않은 경우 그것을보십시오.

참고 사항 : 이미 주어진 모든 답변은 일부 작업으로 인해 서버에 많은 부하가 발생할 수 있다는 사실을 무시하는 것처럼 보입니다. 이는 전력 소비, 하드웨어 소비 및 비용 (CPU주기에 의해 임대 된 서버의 경우)과 관련이 있습니다. 전기 및 유지 관리 비용을 지불하지 않는 일부 임대 서버의 최신 CPU에서 작업을 매우 빠르게 수행 할 수있는 경우에도 우수한 개발자는 응용 프로그램 최적화에 게을러서는 안됩니다.

질문이 몇 살이되었지만 내 답변이 여전히 도움이되기를 바랍니다.


4
나는 일반적으로이 정서에 동의하지만, 세션 식별자조차도 서버에 저장해서는 안된다는 주장이 최근에 퍼졌습니다. 대안 솔루션이 무엇인지 아직 알지 못했지만 JWT는 잘 알려져 있지만 다음과 같은 몇 가지 문제점이 있습니다. cryto.net/~joepie91/blog/2016/06/19/…
BeniRose

11

상태 비 저장은 서비스 상태가 후속 요청과 응답 사이에 지속되지 않음을 의미합니다. 각 요청에는 고유 한 사용자 자격 증명이 있으며 개별적으로 인증됩니다. 그러나 상태 저장에서 각 요청은 이전 요청에서 알려져 있습니다. 모든 상태 저장 요청은 세션 지향적입니다. 즉, 각 요청은 이전 요청의 변경 사항을 알고 유지해야합니다.

은행 응용 프로그램은 상태 저장 응용 프로그램의 예입니다. 사용자가 처음 로그인하면 거래를하고 로그 아웃합니다. 로그 아웃 한 후 사용자가 트랜잭션을 시도하면 그렇게 할 수 없습니다.

예, http 프로토콜은 기본적으로 상태 비 저장 프로토콜이지만 상태를 유지하기 위해 HTTP 쿠키를 만듭니다. 따라서 기본적으로 SOAP입니다. 그러나 사용중인 프레임 워크에 따라 마찬가지로 상태를 유지할 수 있습니다.

HTTP는 상태가 없지만 다른 세션 추적 메커니즘을 사용하여 Java 애플리케이션에서 세션을 유지할 수 있습니다.

예, REST이든 SOAP이든 웹 서비스에서 세션을 유지할 수도 있습니다. 타사 라이브러리를 사용하여 구현하거나 자체적으로 구현할 수 있습니다.

http://gopaldas.org/webservices/soap/webservice-is-stateful-or-stateless-rest-soap 에서 가져온


11

숟가락이 없다.

" 모든 것을 서버에 반복해서 전송 하는 것"과 같은 상태 비 저장을 생각하지 마십시오 . 절대 안돼. 상태는 항상 있습니다-데이터베이스 자체 결국 일종의 상태입니다. 등록 된 사용자이므로 클라이언트 측 정보 세트는 서버 측이 없으면 유효하지 않습니다. 기술적으로, 당신은 결코 진정으로 무국적자 .

매번 로그인 에 관한 단어토론 할

세션을 유지하지 않고 매번 로그인하지 않는다는 것은 무엇을 의미합니까? 어떤 사람들은 "매번 암호를 보내라"는 말은 그냥 바보입니다. 어떤 사람들은 "물론 토큰을 보내지 말라"고 말합니다 . PHP 세션이 거의 정확하게 작동하고 있습니다. 일종의 토큰 인 세션 ID 를 보냅니다. 매번 u / pw를 다시 보내지 않고도 개인 물건에 도달하는 데 도움이됩니다. 또한 매우 신뢰할 수 있고 잘 테스트되었습니다. 그리고 네, 편리하고 단점은 다음 단락을 참조하십시오.

발자국 감소

당신은 무엇을 해야합니까 , 대신, 진짜 의미가 무엇을 최소로 웹 서버 공간 얇은입니다. PHP와 같은 언어를 사용하면 세션 저장소에 모든 것을 넣기가 매우 쉬워 지지만 세션에는 가격표가 있습니다. 웹 서버가 여러 개인 경우로드를 공유하기 때문에 세션 정보를 공유해야합니다. 다음 요청을 처리해야 할 수도 있습니다.

공유 스토리지는 필수입니다. 서버는 누군가가 로그인했는지 여부를 알아야합니다. (그리고 결정을 할 때마다 데이터베이스를 귀찮게하면 실제로 운명에 처하게됩니다.) 공유 스토리지는 데이터베이스보다 훨씬 빨라야합니다. 이것은 유혹을 가져옵니다. 좋아요, 매우 빠른 저장 공간이 있습니다. 왜 모든 것을 거기에서하지 않습니까? 그리고 그것은 다른 방식으로 불쾌한 곳입니다.

세션 스토리지를 최소한으로 유지 하시겠습니까?

다시, 그것은 당신의 결정입니다. 성능상의 이유로 물건을 저장할 수 있습니다 (데이터베이스는 거의 항상 Redis보다 느립니다). 중복 정보를 저장하고 자신의 캐싱을 구현할 수 있습니다. 무엇이든 쓰레기를 많이 저장하면 웹 서버의 부하가 커진다 그들에. 또한,로드가 과중한 경우 (그리고 그렇게 될 경우) 귀중한 정보를 잃게됩니다. REST 사고 방식을 사용하면이 경우에 발생하는 모든 것은 클라이언트가 동일한 (!) 요청을 다시 보내고 이번에는 제공됩니다.

그때 어떻게해야합니까?

여기에 맞는 솔루션은 없습니다. 나는 무국적 수준을 선택하고 그와 함께 가라고 말하고 싶습니다. 세션은 일부 사람들에게 사랑 받고 다른 사람들에게는 미움을받을 수 있지만 아무데도 가지 않습니다. 모든 요청에 ​​대해 이해하기 쉬운 정보를 조금 더 보내십시오. 그러나 상태 비 저장이 세션이 없거나 매번 로그인하는 것으로 해석하지 마십시오. 어떻게 든 서버가 당신인지 알아야합니다. 이라는 . PHP 세션 ID는 좋은 방법이며, 수동으로 생성 된 토큰은 다른 방법입니다.

디자인 트렌드가 당신을 생각하게하지 마십시오.


1
"생각하고 결정하십시오. 디자인 트렌드가 당신을 생각하게하지 마십시오." 불행히도 요즘에는 어리석게 트렌드를 따르는 것이 매우 일반적입니다. 때로는 SO를 읽으면 추세 때문에 동일한 대답을 얻을 수 있습니다.
l00k

그렇습니다. 나는 많은 주제에서 이것을 보았고, 무슨 일이 일어나고 있는지 깨달을 때 때때로 논쟁을 멈추게됩니다. 당시에는 모든 사람들이 콘텐츠 상자가 테두리 상자보다 나은 점에 열중했습니다. IE에 대한 증오를 보여주는 한 가지 방법이었습니다. 그런 다음 부트 스트랩이 왔고 갑자기 모든 사람들이 국경 상자를 믿는 사람이었습니다. 트렌드가 오지만 그들은 간다. goto를 사용하고, 테이블을 사용하고, iframe을 사용하고, 현재하고있는 일과 이유 만 알면됩니다. 트렌드리스트는 귀하를 데려 오려고 시도한 다음 귀하의 사이트에 등록하여 비용을 지불합니다. 세계는 다시 구했다.
dkellner

@dkellner 나는 그 부분을 이해하지 못했습니다 : "적어도 누군가가 로그인했는지 여부를 서버가 알아야합니다. PHP를 사용하여 세션 데이터를 데이터베이스에 저장한다고 가정하십시오. PHP 세션 ID를 기반으로 완전한 사용자 데이터 및 기타 정보를 얻기 위해 많은 후속 DB 요청이 있기 때문에 로그인에 대해 DB에 쿼리하는 것이 왜 좋지 않습니까? 즉, DB 쿼리는 어떤 경우에도 불가피합니다. 또한 PHP 세션 ID를받지 못하면 사용자가 인증되지 않은 것이므로 쿼리 할 필요가 없습니다.
user2923322

수천 명 또는 수백만 명의 사용자가있는 경우 Keepalive, 위치 업데이트, 메시지 폴링 또는 간단한 체크인이 필요한 항목을 수행 할 때마다 db에 연결할 수 없습니다. 데이터베이스 액세스없이 (또는 최소한의) 이러한 호출을 구현해야하므로 db에 대한 전체 개념을 구축하면 치명적일 수 있습니다. 잘 설계된 db 솔루션이 작동하는 경우도있을 수 있지만 일반적인 프로그래머는 "좋아요, 먼저 일부 사용자 정보를 연결하고 가져옵니다"라고 말하면 모든 문제를 해결할 수 있습니다. Baaaad 연습.
dkellner


3

Stateless와 Stateful의 주요 차이점은 매번 서버로 데이터가 전달된다는 것입니다. 상태 비 저장의 경우 클라이언트는 모든 정보를 제공해야하므로 각 요청에서 많은 매개 변수를 전달해야합니다. Stateful에서 클리트는 해당 매개 변수를 한 번 전달하고 클라이언트가 다시 수정할 때까지 서버에서 유지 보수합니다.

IMO, API는 상태가 없어야하므로 실제로 빠르게 확장 할 수 있습니다.


2

클라이언트 쪽에서 클라이언트 세션을 관리해야합니다. 즉, 모든 요청과 함께 인증 데이터를 보내야하며 서버에 인 메모리 캐시가 있어야 할 필요는 없지만 인증 데이터를 ID, 권한 등과 같은 사용자 정보와 쌍을 이룹니다.

이 REST Statelessness 제약 조건 은 매우 중요합니다. 이 제약 조건을 적용하지 않으면 모든 단일 클라이언트 세션을 유지 관리하는 것이 Achilles 'heel 이기 때문에 서버 측 응용 프로그램의 확장 성떨어 집니다.


각 요청과 함께 인증 데이터를 보내는 경우 사용자가 모든 요청에 ​​대해 자격 증명을 다시 입력 할 필요가 없도록 자격 증명을 클라이언트에서 어디에 / 어떻게 저장합니까?
Amber

1

RESTful 서비스를 개발할 때 로그인하려면 사용자를 인증해야합니다. 가능한 옵션은 사용자 작업을 수행 할 때마다 사용자 이름과 비밀번호를 보내는 것입니다. 이 경우 서버는 세션 데이터를 전혀 저장하지 않습니다.

또 다른 옵션은 서버에서 session-id를 생성하여 클라이언트로 전송하는 것이므로 클라이언트는 session-id를 서버로 보내고 인증 할 수 있습니다. 누군가가 해당 데이터를 가져 오면 사용자 이름과 비밀번호가 변경 될 때까지 사용자를 가장 할 수 있으므로 매번 사용자 이름과 비밀번호를 보내는 것보다 훨씬 안전합니다. 세션 ID조차 도난 당할 수 있으며 그 경우 사용자가 가장되어 있다고 말할 수 있습니다. 그러나이 경우 사용자를 가장하는 것은 세션 ID가 유효한 동안에 만 가능합니다.

RESTful API가 사용자 이름과 비밀번호를 변경하기 위해 사용자 이름과 비밀번호를 예상하는 경우 누군가가 세션 ID를 사용하여 사용자를 가장 한 경우에도 해커는 실제 사용자를 잠글 수 없습니다.

세션 ID는 사용자를 식별하고 세션 ID에 시간을 추가하는 무언가의 단방향 잠금 (암호화)에 의해 생성 될 수 있으며, 이러한 방식으로 세션 만료 시간을 정의 할 수 있습니다.

서버는 세션 ID를 저장하거나 저장하지 않을 수 있습니다. 물론 서버가 세션 ID를 저장하면 질문에 정의 된 기준을 위반하게됩니다. 그러나 지정된 사용자에 대해 세션 ID를 확인할 수 있어야 세션 ID를 저장할 필요가 없습니다. 이메일, 사용자 ID 및 선호하는 색상과 같은 일부 사용자 별 개인 데이터를 단방향으로 암호화하는 방법을 상상해보십시오. 이는 첫 번째 수준이며 사용자 이름 날짜를 암호화 된 문자열에 추가하고 두 가지를 적용합니다. 암호화. 결과적으로 세션 ID가 수신되면, 사용자가 주장하는 사용자 이름과 세션 시간이 올바른지 여부를 판단 할 수 있도록 두 번째 수준을 해독 할 수 있습니다. 이것이 유효하면 그런 다음 암호화를 다시 수행하고 문자열과 일치하는지 확인하여 첫 번째 암호화 레벨을 검증 할 수 있습니다. 이를 달성하기 위해 세션 데이터를 저장할 필요가 없습니다.


이 차종의 의미
mestarted

0

전체 개념이 다릅니다 ... RESTFul 프로토콜을 구현하려는 경우 세션을 관리 할 필요가 없습니다. 이 경우 모든 요청에 ​​대해 인증 절차를 수행하는 것이 좋습니다 (성능 측면에서 추가 비용이 발생하지만 해싱 암호는 좋은 예입니다. 큰 문제는 아닙니다). 세션을 사용하는 경우 어떻게 여러 서버에로드를 분산시킬 수 있습니까? RESTFul 프로토콜은 세션을 제거하기위한 것입니다. 실제로 필요하지는 않습니다. 이것이 "무국적"이라고 불리는 이유입니다. 세션은 요청이 이루어진 후 클라이언트 측에 쿠키 이외의 것을 저장할 수없는 경우에만 필요합니다 (예를 들어, Javascript / HTML5를 지원하지 않는 오래된 브라우저를 사용하십시오). "모든 기능을 갖춘"RESTFul 클라이언트의 경우 일반적으로 저장하는 것이 안전합니다base64(login:password) 응용 프로그램이 여전히로드 될 때까지 클라이언트 측 (메모리)에서-응용 프로그램이 유일한 호스트에 액세스하는 데 사용되며 타사 스크립트로 쿠키를 손상시킬 수 없습니다 ...

RESTFul 서비스에 쿠키 인증을 비활성화하는 것이 좋습니다 ... 기본 / 다이제스트 인증을 확인하십시오-RESTFul 기반 서비스에 충분해야합니다.


3
클라이언트 측 a client side (in memory) 에 저장하는 것이 무엇 이고 어떻게 안전 base64(login:password)합니까?
RN Kushwaha

1
"완전히 안전한"것으로 정의 된 것은 없습니다. 그러나 API 요청 (기본 인증)을 위해 base64 문자열을 저장하는 것보다 더 나은 보안을 제공하는 OAuth2를 사용하는 것을 고려할 수 있습니다. 기본 인증을 사용하는 경우 HTTPS를 사용하여 보안을 강화할 수 있습니다.
felixwcf

3
RN Kushwaha, 이것은 서버에서 세션 저장을 중지하고 클라이언트에 저장하라고 말할 때 아무도 대답하고 싶지 않은 질문입니다.
BeniRose

0

REST는 상태 비 저장이며 요청간에 상태를 유지하지 않습니다. 클라이언트 쿠키 / 헤더는 인증과 같은 사용자 상태를 유지하도록 설정됩니다. 클라이언트 사용자 이름 / 암호는 3 단계 인증 메커니즘 (2 단계 OTP gerneation 등)에 의해 검증됩니다. 일단 사용자가 인증되면 – 헤더 / 쿠키가 서비스 엔드 포인트 노출 상태가되고 사용자가 유효한 헤더 / 쿠키를 가지고 있기 때문에 사용자를 인증 된 것으로 간주 할 수 있습니다. . 이제 IP와 같은 특정 사용자 정보가 캐시에 유지되고 그 후 요청이 나열된 리소스에 대해 동일한 IP (mac 주소)에서 온 경우 사용자가 허용됩니다. 캐시는 특정 시간 동안 유지되며 시간이 지나면 무효화됩니다. 따라서 캐시를 사용하거나 DB 항목을 사용하여 요청 정보를 유지할 수 있습니다.


0

여기서 상태 비 저장은 요청의 상태 또는 메타 데이터가 서버 측에서 유지되지 않음을 의미합니다. 서버에서 각 요청 또는 사용자 상태를 유지하면 성능 병목 현상이 발생합니다. 특정 작업을 수행하기 위해 서버에 필수 속성이 요청되었습니다.

세션을 관리하거나 사용자에게 사용자 정의 경험을 제공하려면 일부 메타 데이터 또는 사용자 요청 가능성이 높은 사용자 상태, 과거 요청 기록을 유지해야합니다. 쿠키, 숨겨진 속성 또는 세션 객체를 유지하여 수행 할 수 있습니다.

이를 통해 응용 프로그램에서 사용자 상태를 유지하거나 추적 할 수 있습니다.

도움이 되었기를 바랍니다!

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