티스토리 뷰

웹개발/Php

OAuth 정리

야쿠 yaku 2012.01.19 13:28

용어정의

  • 서비스 프로바이더(Service Provider) – API를 제공하는 서비스를 말합니다. 예> 스프링노트
  • 사용자(users) - 서비스 프로바이더 혹은(그리고) 컨수머를 사용하는 이를 말합니다. 
  • 컨수머(Consumer) – API를 사용하여 개발된 애플리케이션 서비스를 말합니다. 예> 스프링노트의 API를 이용하여 개발된 매시업
  • 보호된 자원(Protected Resources): 서비스 프로바이더에 존재하는 사용자의 데이터를 의미합니다. 예> 스프링노트의 페이지 혹은 첨부 데이터들
  • 컨수머 개발자(Consumer Developer) : 컨수머를 개발하는 개인 혹은 단체
  • 컨수머 키(Consumer Key) : 서비스 프로바이더에게 컨수머 자신임을 인증하기 위한 키
  • 컨수머 시크릿(Consumer Secret) : 컨수머컨수머 키 소유권한이 있는지 인증하기 위한 키
  • 토큰(Tokens) – 컨수머에서 서비스 프로바이더에 있는 사용자보호된 자원에 접근하기 위해 사용되는 사용자의 인증정보입니다. 예를들어 스프링노트의 API를 사용해 개발된 매시업 M이 스프링노트(서비스 프로바이더)에 있는 사용자 U의  보호된 데이터에 접근하기 위해서는 사용자 U의 인증정보(credential)가 필요합니다. 그 인증정보를 위해 사용되는 것이 토큰입니다.

    • 리퀘스트 토큰(Request Token) :  컨수머사용자에게  접근권환을 획득하는 과정에서 사용하는 값이며, 이것은 차후 액세스 토큰으로 교환됩니다.
    • 리퀘스트 토큰 시크릿(Request Token Secret) :  리퀘스트토큰이 사용자의 것임을 인증하기 위한 값입니다.
    • 액세스 토큰(Access Token) : 컨수머사용자서비스 프로바이더를 통해서가 아닌 컨수머를 통해서 보호된 자원에 접근할 수 있는 권한을 받기 위한 값입니다.
    • 액세스 토큰 시크릿(Access Token Secret) : 액세스토큰사용자의 것임을 인증하기 위한 값입니다.

 

보안 고려사항

부록 : 프로토콜 예제

  • 서비스 프로바이더가 사진을 공유하는 웹사이트(photos.example.net)이고, 컨슈머는 사진 인화 사이트(printer.example.com)이라고 가정합니다. 사용자 Jane은 printer.example.com(이하 '출력 사이트')에서 photo.example.net(이하 '사진 사이트')에 저장된 비공개 사진 vacation.jpg을 출력하려는 상황을 예로 설명합니다.
  • Jane은 photo.example.net에 로그인해서 사진 URL http://photo.example.net/photo?file=vacation.jpg를 알아냈습니다. 다른 사용자는 이 사진을 볼 수 없고, Jane은 아이디와 패스워드를 printer.example.com에 저장하기 꺼림칙해합니다.
  • 이 예재의 요청은 파라미터를 보낼 때 URL 쿼리 메소드를 사용합니다. 이것은 예재를 간단히 보여주기 위한 것이지 다른 곳에도 보증된 메소드는 아닙니다.
1. 설명서와 등록
  • 서비스 프로바이더 설명서는 컨슈머 키와 컨슈머 시크릿을 어떻게 등록하는지와 다음 URL에 대한 안내가 있어야 합니다.
    Request 토큰 URL
    https://photos.example.net/request_token / HTTP POST 사용
    사용자 인증 URL
    http://photos.example.net/authorize / HTTP GET 사용
    Access 토큰 URL
    https://photos.example.net/access_token / HTTP POST 사용
    Photo(보호된 리소스) UR
    http://photo.example.net/photo / file 파라미터가 필요하고 옵션으로 size 파라미터가 있음
  • 서비스 프로바이더는 HMAC-SHA1 서명 메소드를 모든 요청에 지원하고, PLAINTEXT는 보안(HTTPS) 요청에만 지원합니다.
  • 컨슈머 출력 사이트는 사진 사이트에 컨슈머 키와 컨슈머 시크릿을 이미 생성하고, 사진 사이트의 사진을 프린트가 되게 작성해 놓은 상태입니다. 컨슈머 등록 코드는 다음과 같습니다.
    컨슈머 키
    dpf43f3p2l4k3l03
    컨슈머 시크릿
    kd94hf93k423kf44
2. Request 토큰 획득
  • Jane은 출력 사이트에서 사진 사이트에 있는 휴가 사진을 출력을 하려 했지만 출력 사이트에서 사진에 접근하려 하자 비공개 사진이라는 다음 헤더와 함께 HTTP 401 Unauthorized 코드를 응답 받았습니다.
    WWW-Authenticate: OAuth realm="http://photos.example.net/"
  • 컨슈머는 다음 HTTP POST 요청을 서비스 프로바이더에 보냅니다.
    https://photos.example.net/request_token?oauth_consumer_key=dpf43f3p2l4k3l03&oauth_signature_method=PLAINTEXT &oauth_signature=kd94hf93k423kf44%26&oauth_timestamp=1191242090 &oauth_nonce=hsu94j3884jdopsl&oauth_version=1.0&oauth_callback=http%3A%2F%2Fprinter.example.com%2Frequest_token_ready
    https://photos.example.net/request_token?oauth_consumer_key=[컨슈머 키]&oauth_signature_method=[서명 메소드] &oauth_signature=[URL 인코딩한 '컨슈머 시크릿&토큰 시크릿'(토큰 시크릿은 아직 없으니 '컨슈머 시크릿&')]&oauth_timestamp=[타임스탬프] &oauth_nonce=[nonce]&oauth_version=[OAuth 버전]&oauth_callback=[URL 인코딩한 콜백 URL]
  • 서비스 프로바이더는 서명을 확인하고 인증되지 않은 Request 토큰을 HTTP response body에 실어 응답합니다.
    oauth_token=hh5s93j4hdidpola&oauth_token_secret=hdhd0244k9j7ao03&oauth_callback_confirmed=true
    oauth_token=[생성한 Request 토큰]&oauth_token_secret=[생성한 토큰 시크릿]&oauth_callback_confirmed=[콜백 허용]
3. 사용자 인증 요청
  • 컨슈머는 비공개 사진에 접근하는 승인을 얻기 위해 Jane의 브라우저를 서비스 프로바이더의 사용자 인증 URL로 이동시킵니다.
    http://photos.example.net/authorize?oauth_token=hh5s93j4hdidpola
    http://photos.example.net/authorize?oauth_token=[프로바이더에서 받은 Request 토큰]
  • 서비스 프로바이더는 Jane에게 로그인 한 후 출력 사이트에 비공개 사진에 접근을 허용을 요청합니다. Jane이 요청을 허용하면 서비스 프로바이더는 검증 코드를 생성하고 컨슈머의 콜백 URL로 보냅니다.
    http://printer.example.com/request_token_ready?oauth_token=hh5s93j4hdidpola&oauth_verifier=hfdp7dh39dks9884
    http://printer.example.com/request_token_ready?oauth_token=[Request 토큰]&oauth_verifier=[생성한 검증코드]
4. Access 토큰 획득
  • 이제 컨슈머는 Jane의 인증된 Request 토큰을 가지고 있으니 이것을 서비스 프로바이더에서 Access 토큰으로 교환해야 합니다.
    https://photos.example.net/access_token?oauth_consumer_key=dpf43f3p2l4k3l03&oauth_token=hh5s93j4hdidpola &oauth_signature_method=PLAINTEXT&oauth_signature=kd94hf93k423kf44%26hdhd0244k9j7ao03&oauth_timestamp=1191242092 &oauth_nonce=dji430splmx33448&oauth_version=1.0&oauth_verifier=hfdp7dh39dks9884
    https://photos.example.net/access_token?oauth_consumer_key=[컨슈머 키]&oauth_token=[Request 토큰] &oauth_signature_method=[서명 메소드]&oauth_signature=[URL 인코딩한 '컨슈머 시크릿&토큰 시크릿']&oauth_timestamp=[타임스탬프] &oauth_nonce=[nonce]&oauth_version=[OAuth 버전]&oauth_verifier=[검증코드]
  • 서비스 프로바이더는 서명과 검증 코드를 확인하고, Access 토큰을 HTTP response body에 실어 응답합니다.
    oauth_token=nnch734d00sl2jdk&oauth_token_secret=pfkkdhi9sl3r4s00
    oauth_token=[생성한 Access 토큰]&oauth_token_secret=[새로 생성한 토큰 시크릿]
5. 보호된 리소스에 접근하기

컨슈머는 이제 비공개 사진에 접근할 수 있습니다. 사진 URL이 비보안 프로토콜(HTTP)에 있기 때문에 HMAC-SHA1을 사용해야 합니다.

1. Signature 기본 문자열 생성
  • 서명을 만들기 위해서는 우선적으로 Signature 기본 문자열을 생성해야 합니다. 요청은 다음 파라미터(oauth_signature 제외)를 포함합니다.
    oauth_consumer_key
    dpf43f3p2l4k3l03 (컨슈머 키)
    oauth_token
    nnch734d00sl2jdk (Access 토큰)
    oauth_signature_method
    HMAC-SHA1 (서명 메소드)
    oauth_timestamp
    1191242096 (타임 스탬프)
    oauth_nonce
    kllo9940pd9333jh (nonce)
    oauth_version
    1.0 (OAuth 버전)
    file
    vacation.jpg (추가 파라미터)
    size
    original (추가 파라미터)
  • Signature 기본 문자열을 생성할 때 다음 입력들이 사용됩니다.
    • GET (HTTP 메소드)
    • http://photos.example.net/photos (파라미터를 제외한 절대 경로)
    • file=vacation.jpg
      &oauth_consumer_key=dpf43f3p2l4k3l03
      &oauth_nonce=kllo9940pd9333jh
      &oauth_signature_method=HMAC-SHA1
      &oauth_timestamp=1191242096
      &oauth_token=nnch734d00sl2jdk
      &oauth_version=1.0
      &size=original
  • 생성된 Signature 기본 문자열 (위의 3가지를 URL 인코딩한 후 &로 연결)
    GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal
2. Signature 값 계산
  • HMAC-SHA1로 base64 인코딩해서 다음의 Signature를 만들어 냅니다(text로는 Signature 기본 문자열을, key로는 kd94hf93k423kf44&pfkkdhi9sl3r4s00(컨슈머 시크릿 & 토큰 시크릿)를 사용).
    tR3+Ty81lMeYAr/Fid0kMTYa/WM=
3. 보호된 리소스 요청
  • 결과적으로 컨슈머는 사진을 요청하기 위해 다음의 내용을 사용합니다.

    http://photos.example.net/photos?file=vacation.jpg&size=original

    Authorization: OAuth realm="http://photos.example.net/",
    oauth_consumer_key="dpf43f3p2l4k3l03",
    oauth_token="nnch734d00sl2jdk",
    oauth_signature_method="HMAC-SHA1",
    oauth_signature="tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D", (생성된 Signature를 URL 인코딩)
    oauth_timestamp="1191242096",
    oauth_nonce="kllo9940pd9333jh",
    oauth_version="1.0"

    이것을 쿼리 파라미터로 사용하면 다음과 같이 됩니다.

    http://photos.example.net/photos?file=vacation.jpg
    &size=original
    &oauth_consumer_key=dpf43f3p2l4k3l03
    &oauth_token=nnch734d00sl2jdk
    &oauth_signature_method=HMAC-SHA1
    &oauth_signature=tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D
    &oauth_timestamp=1191242096
    &oauth_nonce=kllo9940pd9333jh
    &oauth_version=1.0

  • 사진 사이트는 이 서명을 확인하고 요청된 사진을 응답으로 보냅니다.
저작자 표시
신고

'웹개발 > Php' 카테고리의 다른 글

ReflectionClass 클래스를 사용하여 인스턴스 얻기  (0) 2012.02.02
PHP curl_setopt  (1) 2012.01.20
OAuth 정리  (0) 2012.01.19
PHP 파일 모드 간단 설명  (0) 2012.01.11
PHP 정규 표현식 10가지 사용 예제  (2) 2011.09.06
Kohana Validation 체크  (0) 2011.08.26
댓글
댓글쓰기 폼