RESTful 웹 서비스에서 로그인을 어떻게 구현합니까?


78

서비스 레이어로 웹 애플리케이션을 구축하고 있습니다. 서비스 계층은 RESTful 디자인을 사용하여 구축 될 것입니다. 향후 언젠가는 웹 애플리케이션과 동일한 서비스 계층을 사용하는 다른 애플리케이션 (iPhone, Android 등)을 구축 할 수 있다고 생각합니다. 내 질문은 이것이다-어떻게 로그인을 구현합니까? 전통적인 동사 기반 디자인에서 리소스 기반 디자인으로 이동하는 데 어려움이 있다고 생각합니다. SOAP로 이것을 구축했다면 아마도 Login이라는 메서드가있을 것입니다. REST에서는 리소스가 있어야합니다. 로그인을 위해 URI를 구성하는 방법을 이해하는 데 어려움이 있습니다. 다음과 같을까요?

http : // myservice / {username}? p = {password}

편집 : 프런트 엔드 웹 응용 프로그램은 인증을 위해 기존 ASP.NET 프레임 워크를 사용합니다. 그러나 인증 프로세스의 어느 시점에서 제공된 자격 증명의 유효성을 검사해야합니다. 전통적인 웹 애플리케이션에서는 데이터베이스 조회를 수행합니다. 하지만이 시나리오에서는 데이터베이스 조회를 수행하는 대신 서비스를 호출합니다. 따라서 제공된 자격 증명의 유효성을 검사 할 서비스가 필요합니다. 그리고 제공된 자격 증명의 유효성을 검사하는 것 외에도 사용자가 성공적으로 인증 한 후 사용자에 대한 정보 (성명, ID 등)가 필요할 수 있습니다. 이것이 질문을 더 명확하게 해주기를 바랍니다.

아니면 내가 이것에 대해 올바른 방식으로 생각하고 있지 않습니까? 내 질문을 올바르게 설명하는 데 어려움이있는 것 같습니다.

Corey

답변:


62

S.Lott가 이미 지적했듯이 여기에는 로그인과 인증이라는 두 가지 접힌 부분이 있습니다.

여기에서 인증은 광범위하게 논의되고 공통된 동의가 있기 때문에 범위를 벗어납니다. 그러나 클라이언트가 RESTful 웹 서비스에 대해 성공적으로 인증하기 위해 실제로 필요한 것은 무엇입니까? 맞습니다. 일종의 토큰입니다. 액세스 토큰이라고합시다.

클라이언트) 그래서, 필요한 것은 액세스 토큰 뿐이지 만 RESTfully을 얻는 방법은 무엇입니까?
서버) 단순히 생성하지 않는 이유는 무엇입니까?
Client) 어떻게 오나요?
서버) 나에게 액세스 토큰은 리소스에 지나지 않습니다. 따라서 사용자 이름과 암호를 대신하여 하나를 만들 것입니다.

따라서 서버는 사용자 이름과 암호를 게시하기 위해 리소스 URL "/ accesstokens"를 제공하여 새로 생성 된 리소스 "/ accesstokens / {accesstoken}"에 대한 링크를 반환 할 수 있습니다. 또는 리소스 링크와 함께 액세스 토큰 및 href가 포함 된 문서를 반환합니다.

<액세스 토큰
  id = "{액세스 토큰 ID가 여기에 표시됩니다. 예 : GUID}"
  href = "/ accesstokens / {id}"
/>

대부분의 경우 실제로 액세스 토큰을 하위 리소스로 생성하지 않으므로 해당 href를 응답에 포함하지 않을 것입니다.
그러나 그렇게하면 클라이언트가 대신 링크를 생성 할 수 있습니까? 아니!
진정한 RESTful 웹 서비스는 클라이언트가 리소스 링크를 생성 할 필요없이 스스로 탐색 할 수있는 방식으로 리소스를 함께 연결합니다.

마지막 질문은 사용자 이름과 비밀번호를 HTML 형식이나 문서 (예 : XML 또는 JSON)로 게시해야하는지 여부입니다. 상황에 따라 다릅니다. :-)


4
REST를 완벽하게 따르지는 않지만 다른 것보다 간단하고 측정 가능합니다. 또한 좋은 유머와 공유했습니다.
Ted Johnson

2
패트릭,이 대답과 같은 것을 제안하고 있습니까? stackoverflow.com/a/1135995/14731
Gili

사용자 이름 및 / 또는 암호가 일치하지 않을 때 403 올바른 상태 코드입니까?
tsobe

무슨 생각. 'accesstoken'리소스를 만드는 중입니다.
Sorter 2015

25

당신은 "로그인"하지 않습니다. 당신은 "인증"합니다. 차이의 세계.

많은 인증 대안이 있습니다.

HTTP 기본, 다이제스트, NTLM 및 AWS S3 인증

  • HTTP 기본 및 다이제스트 인증. 이것은 HTTP_AUTHORIZATION헤더를 사용합니다 . 이것은 매우 훌륭하고 매우 간단합니다. 그러나 많은 트래픽이 발생할 수 있습니다.

  • 사용자 이름 / 서명 인증. "ID 및 KEY"인증이라고도합니다. 쿼리 문자열을 사용할 수 있습니다.

    ?username=this&signature=some-big-hex-digest

    이것은 Amazon과 같은 곳에서 사용하는 것입니다. 사용자 이름은 "id"입니다. "키"는 HTTP Digest 인증에 사용되는 것과 유사한 다이제스트입니다. 진행하려면 양쪽 모두 다이제스트에 동의해야합니다.

  • 일종의 쿠키 기반 인증. 예를 들어 OpenAM 은 RESTful 웹 서버가 사용할 수있는 쿠키를 인증하고 제공하는 에이전트로 구성 될 수 있습니다. 클라이언트는 먼저 인증 한 다음 각 RESTful 요청에 쿠키를 제공합니다.


2
@ S.Lott @Corey 사용자는 절대적으로 RESTful 시스템과 상호 작용할 수 있습니다. 대부분의 정적 HTML 웹 사이트는 RESTful "서비스"입니다.
Darrel Miller

7
@Darrel Miller : "당신의 아이디어는 ... 결함이 있습니다"는 적절한 맥락이나 유용한 정보를 제공하지 않습니다. 그것은 일종의 부정적이고별로 도움이되지 않습니다.
S.Lott 2011 년

5
@Darrel Miller : "REST가 제한적이라는 주장은 우스꽝 스럽습니다." 도대체 무엇이. 오히려 틀린 것을 반복하십시오. 옳은 것이 무엇인지 설명해 주시겠습니까? 부정적인 진술 대신 단순한 긍정적 인 진술을 제공 할 수 있습니까? REST가 아닌 것 대신에 REST가 무엇인지 설명해 주시겠습니까? 그렇지 않은 것에는 무한한 수가 있습니다.
S.Lott 2011 년

4
@Darrel Miller : 5.2.1.2 표현이 꽤 분명해 보입니다. 귀하의 의견은 매우 부정적입니다. 부정적이 아닌 긍정적 인 수정이나 업데이트를 제공 할 수 있습니까? 당신이하는 모든 일은 내가 어떻게 든 "결함이있다", "잘못된 정보를 퍼 뜨리고있다"또는 "어리 석다"고 말하는 것이므로 당신을 만족시키기 위해 내 대답을 수정하거나 수정하는 방법을 알아낼 수 없습니다. 결함이 덜하거나 부정확하거나 덜 우스운 것은 무엇입니까?
S.Lott 2011 년

5
@ S.Lott 1) ​​사용자는 항상 RESTful 시스템과 상호 작용합니다. 2) HTML은 RESTful 시스템이 반환 할 수있는 완벽하게 유효한 미디어 유형입니다. 3) REST는 HTTP의 하위 집합이 아닙니다. REST는 아키텍처 스타일이고 HTTP는 프로토콜입니다. 4) RESTful 시스템은 "웹 서비스"에 국한되지 않습니다. 5) RESTful 시스템은 세션과 관련된 문제없이 특정 형태의 인증 토큰을 사용하여 로그인을 시뮬레이션 할 수 있습니다.
Darrel Miller 2011 년

1

좋은 질문입니다. 나는 패트릭의 대답을 정말 좋아합니다. 나는 다음과 같은 것을 사용한다.

-/ users / {사용자 이름} / loginsession

POST 및 GET이 처리됩니다. 따라서 자격 증명이있는 새 로그인 세션을 게시 한 다음 GET을 통해 현재 세션을 리소스로 볼 수 있습니다.

리소스는 로그인 세션이며 액세스 토큰 또는 인증 코드, 만료 등이있을 수 있습니다.

이상하게도 내 MVC 호출자는 MVC 사이트가 API의 클라이언트이기 때문에 새 로그인 세션을 시도하고 만들 수있는 권한이 있음을 증명하기 위해 헤더를 통해 키 / 보유자 토큰을 제시해야합니다.

편집하다

여기에 다른 답변과 의견이 대역 외 공유 비밀로 문제를 해결하고 헤더로 인증한다고 생각합니다. 많은 상황에서 또는 서비스 간 호출에 적합합니다.

다른 솔루션은 토큰, OAuth 또는 JWT 또는 기타 흐름을 보내는 것입니다. 즉, POST 양식을 기반으로하는 브라우저의 일반 로그인 UI와 같은 다른 프로세스에서 이미 "로그인"이 수행되었음을 의미합니다.

내 대답은 사이트 MVC 코드가 아닌 REST 서비스에 로그인 및 인증 및 사용자 관리를 배치하기를 원한다고 가정하고 해당 UI 뒤에있는 서비스에 대한 것입니다. 사용자 로그인 서비스입니다.

또한 다른 서비스가 사전 공유 키를 사용하는 대신 CLI 또는 Postman의 테스트 스크립트를 사용하는 대신 "로그인"하고 만료 토큰을 얻을 수 있습니다.


2
헤더에 토큰을 전달하십시오. URL의 일부로 전달하십시오. URL은 HTTPS를 사용할 때 전송 중에 암호화됩니다. 하나; URL은 브라우저 기록과 서버 로그에도 저장됩니다. URL 쿼리 매개 변수에서 보안에 민감한 데이터를 전달하지 않는 데에는 많은 이유가 있습니다.
Craig

0

2011 년 이후로 많은 변화가 있었기 때문에 ...

타사 도구를 사용할 수 있고 웹 UI에 대해 REST에서 약간 벗어난 경우 http://shiro.apache.org를 고려 하십시오 .

Shiro는 기본적으로 인증 및 권한 부여를위한 서블릿 필터를 제공합니다. 간단한 양식 기반 인증을 포함하여 @ S.Lott에 나열된 모든 로그인 방법을 활용할 수 있습니다.

인증이 필요한 나머지 URL을 필터링하면 Shiro가 나머지 작업을 수행합니다.

나는 현재 내 프로젝트에서 이것을 사용하고 있으며 지금까지 꽤 잘 작동했습니다.

사람들이 관심을 가질만한 다른 것이 있습니다. https://github.com/PE-INTERNATIONAL/shiro-jersey#readme


0

REST에 대해 가장 먼저 이해해야 할 것은 토큰 기반 리소스 액세스라는 것입니다. 기존 방식과 달리 액세스는 토큰 유효성 검사를 기반으로 부여됩니다. 간단히 말해서 올바른 토큰이 있으면 리소스에 액세스 할 수 있으며 이제 토큰 생성 및 조작을위한 다른 많은 항목이 있습니다.

첫 번째 질문에 대해 Restfull API를 설계 할 수 있습니다. Credentials (Username and password) will be passed to your service layer. 서비스 계층은이 자격 증명의 유효성을 검사하고 토큰을 부여합니다. SSL 인증서는 OAUTH 프로토콜을 사용하며 더 안전합니다.

다음과 같이 URI를 설계 할 수 있습니다.-토큰 요청을위한 URI- > http : // myservice / some-directory / token ? (이 URI에서 토큰에 대해 Credentilals를 전달할 수 있습니다.)

리소스 액세스에이 토큰을 사용하려면이 [Authorization : Bearer (token)]을 http 헤더에 추가 할 수 있습니다.

이 토큰은 고객이 서비스 계층의 다른 구성 요소에 액세스하는 데 사용할 수 있습니다. 오용을 방지하기 위해이 토큰의 만료 기간을 변경할 수도 있습니다.

두 번째 질문에 대해 할 수있는 한 가지는 서비스 계층의 다른 리소스 구성 요소에 액세스 할 수 있도록 다른 토큰을 부여하는 것입니다. 이를 위해 토큰에 리소스 매개 변수를 지정하고이 필드를 기반으로하는 그랜드 권한을 지정할 수 있습니다.

자세한 내용은 다음 링크를 따라갈 수도 있습니다. http://www.codeproject.com/Articles/687647/Detailed-Tutorial-for-Building-ASP-NET-WebAPI-REST .

http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api


-4

나는 전에 같은 문제에 직면했습니다. 로그인은 리소스 기반 디자인으로 잘 변환되지 않습니다.

내가 일반적으로 처리하는 방법은 로그인 리소스를 사용하고 매개 변수 문자열에 사용자 이름과 암호를 전달하는 것입니다.

http : // myservice / login? u = {username} & p = {password}에서 GET

응답은 유효성 검사를 위해 다른 API로 전달할 수있는 일종의 세션 또는 인증 문자열입니다.

로그인 리소스에서 GET을 수행하는 대안은 POST를 수행하는 것입니다. REST 순수 주의자들은 아마도 지금 나를 좋아하지 않을 것입니다. :), 그리고 본문에 신임장을 전달합니다. 응답은 동일합니다.


11
암호? 일반 텍스트 암호? 쿼리 문자열로? 정말로 그 뜻입니까, 아니면 암호 요약을 의미합니까?
S.Lott 2011 년

감사. 말이 되네요. 다음은 후속 질문입니다. 대규모 애플리케이션의 경우 모든 것에 대해 하나의 대규모 RESTful 서비스를 만들거나 다른 서비스로 분할 하시겠습니까? 인증을위한 서비스와 애플리케이션의 다른 모듈에 대한 다른 서비스를 생각하고있었습니다. 당신이 어떤 식 으로든 그렇게하려고하거나하지 않을 이유가 있습니까?
Corey Burnett 2011 년

3
S. Lott : 무엇을 하려는지에 따라 다릅니다. 물론 다이제스트를 할 수 있다면 꼭. 때로는 다이제스트가 불가능합니다. 유일한 옵션이 일반 텍스트 암호를 보내는 것이라면 SSL을 통해 수행하십시오.이 경우 브라우저가 보낸 내용을 기억하지 못하도록 GET 대신 POST를 사용하는 것이 좋습니다.
Alex

Corey : 하나의 대형 웹 서비스와 여러 웹 서비스의 차이점을 이해하고 있는지 잘 모르겠습니다. 일반적으로 리소스 측면에서 서비스를 정의하고 의미있는만큼만 추가합니다. 그래도 요점을 놓치고 있다고 생각합니다.
Alex

Alex : 웹 애플리케이션에 보고서, 주문, 다운로드 및 송장의 4 가지 주요 섹션이 있다고 가정 해 보겠습니다. 4 개의 다른 서비스 정의를 갖는 것이 합리적입니까? 아니면 하나의 서비스 정의 만 갖는 것이 합리적입니까? 여러 서비스로 나누고 싶지 않은 특별한 이유가 있습니까?
Corey Burnett 2011 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.