게시:

OAuth 1.0은 OAuth 2.0 보다 사용하는 곳이 적다. OAuth 1.0은 Access token의 만료기간이 없고 인증을 위한 매개변수 중 매개변수 중 signature를 생성하는 과정이 복잡하다.

3rd party client가 Service provider로부터 Access token을 발급받으면 이후 인가가 필요한 API를 호출할 때 Access token을 헤더의 매개변수로 전달하여 해당 사용자를 인증할 수 있다.

OAuth 1.0의 Access token은 한 번 발행되면 만료 전까지 유효하며 서비스 제공자는 해당 Access Token을 신뢰하기 떄문에 Access token이 노출되지 않도록 각별히 주의한다.

관련 용어

OAuth를 이해하려면 용어를 알고 넘어가야 한다. 다음 표는 OAuth 1.0 관련 용어이다.

용어 설명
User Service provider 계정을 보유하고 있으면서 3rd party clien를 사용하려는 이용자
Service provider OAuth를 사용하는 Open API 서비스 제공자
Consumer 3rd party client, OAuth를 사용하여 Service provider의 자원을 사용하려는 서비스
Request token Consumer가 Service provider에게 접근 권한을 인증받기 위해 사용하는 값, 이를 Access token과 교환함
Access token 인증 후 Consumer가 Service provider에게 접근하기 위한 값

주의사항

OAuth 1.0에서 Access token은 자동 만료되지 않는다. Access token을 강제로 De-registration하기 전까지는 Access token가 유효하기 때문에 토큰 정보가 노출되지 않도록 각별히 유의한다.

Service provider 측에 OAuth 인증을 시도하려면 사전에 내 서비스를 Service provider에 등록하여 Consumer key와 Consumer secret을 발급받아야 한다. 이 때 제공받은 Consumer key와 Consumer secret도 절대 노출되지 않도록 주의한다.

인증절차

다음은 OAuth 1.0 인증 절차다. 보편적인 방법을 설명하고 있으나 매개변수나 해싱 알고리즘이 다른 경우도 있으므로 아래 내용은 참고만하고 Service provider의 공식문서의 가이드를 우선으로 한다.

OAuth 1.0 Flow image
참고 이미지: OAuth 1.0 Flow diagram (출처: https://oauth.net)

1. 연결요청

고객이 3rd party client(내 서비스)에서 Service provider(Naver, Kakaotalk, GitHub, Gmail, Facebook etc.)에 ‘연결하기’를 요청한다.

2. Request token 요청

내 서비스가 Service provider에 Access token을 받기 위한 Request token을 요청한다. 매개변수는 Query parameter로 전달하는데 Signature(‘oauth_signature’)는 매개변수들을 활용(조합 및 인코딩)하여 생성해야 한다. 인코딩 알고리즘으로는 많은 곳에서 HMAC-SHA1을 사용하지만 서비스마다 다를 수 있다.다음 목록은 Request에 포함되는 매개변수 목록이다.

  • oauth_consumer_key
  • oauth_nonce
  • oauth_signature
  • oauth_signature_method
  • oauth_timestamp
  • oauth_version (optional)

oauth_signature 생성 방법

OAuth 1.0에서 signature를 생성하는 과정이 가장 까다롭다. 모든 매개변수(Query string)를 조합하여 Consumer secret을 암호화 키로 사용하여 Service provider에서 정하는 방법으로 해싱하여 생성한다.

oauth로 시작하는 매개변수를 모두 모은다.

  oauth_signature_method=HMAC-SHA1
  oauth_consumer_key=sdkfjnwknf2fwieuo2i4
  oauth_version=1.0
  oauth_timestamp=1624495921
  oauth_nonce=wf8923hefjwe # 임의의 문자열
  • 매개변수를 key name의 사전순으로 정렬한 뒤 앰퍼센트(&)로 연결한다.
    oauth_consumer_key=sdkfjnwknf2fwieuo2i4&oauth_nonce=wf8923hefjwe&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1624495921&oauth_version=1.0
      
    # 가독성을 위하여 줄바꿈한 버전
    oauth_consumer_key=sdkfjnwknf2fwieuo2i4&
    oauth_nonce=wf8923hefjwe&
    oauth_signature_method=HMAC-SHA1&
    oauth_timestamp=1624495921&
    oauth_version=1.0
    
  • 연결한 문자열을 URL Encoding(RFC3986)하여 Encoded parameters를 만든다. 파이썬은 urllib 라이브러리를 사용하면 인코딩할 수 있으며 이를 돕는 Online encoder도 있다.
    oauth_consumer_key%3Dsdkfjnwknf2fwieuo2i4%26oauth_nonce%3Dwf8923hefjwe%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1624495921%26oauth_version%3D1.0
      
    # 가독성을 위하여 줄바꿈한 버전
    oauth_consumer_key%3Dsdkfjnwknf2fwieuo2i4%26
    oauth_nonce%3Dwf8923hefjwe%26
    oauth_signature_method%3DHMAC-SHA1%26
    oauth_timestamp%3D1624495921%26
    oauth_version%3D1.0
    
  • Request token을 요청할 URL도 같은 방법으로 Encoding한다.
    # Request token URL 예시
    https://api.exmaple.com/oauth/request-token
      
    # 예시 Encoding
    https%3A%2F%2Fapi.exmaple.com%2Foauth%2Frequest-token
    
  • HTTP 메서드, Encoded request token URL, Encoded parameters를 앰퍼센트(&)로 연결하여 Base string을 만든다.
    POST&https%3A%2F%2Fapi.exmaple.com%2Foauth%2Frequest-token&oauth_consumer_key%3Dsdkfjnwknf2fwieuo2i4%26oauth_nonce%3Dwf8923hefjwe%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1624495921%26oauth_version%3D1.0
      
    # 가독성을 위하여 줄바꿈한 버전
    POST&
    https%3A%2F%2Fapi.exmaple.com%2Foauth%2Frequest-token&
    oauth_consumer_key%3Dsdkfjnwknf2fwieuo2i4%26
    oauth_nonce%3Dwf8923hefjwe%26
    oauth_signature_method%3DHMAC-SHA1%26
    oauth_timestamp%3D1624495921%26
    oauth_version%3D1.0
    
  • Service provider가 정한 알고리즘(예: HMAC-SHA1)으로 Base string을 암호화하여 Signature(oauth_signature)를 만든다. 이 때 암호화 키로는 Consumer secret을 사용한다.

    OAuth 관련 라이브러리를 사용하면 복잡한 과정을 거치지 않고 Signature 손 쉽게 생성할 수 있으며 이후 Request token, Access token 요청 절차도 간편하다. 파이썬의 라이브러리로는 requests_oauthlib가 있다.

    아래 코드 스니펫은 라이브러리 없이 Signature를 생성하는 코드 예시이다.

    # HMAC-SHA1 암호화 예시 (Python code snippet)
      
    import base64
    from hashlib import sha1
      
    _KEY = b'2fn4usndfunpuifninwefansdjnlkds&' # Consumer secret
    _BASE_STR = b'POST&https%3A%2F%2Fapi.exmaple.com%2Foauth%2Frequest-token&oauth_consumer_key%3Dsdkfjnwknf2fwieuo2i4%26oauth_nonce%3Dwf8923hefjwe%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1624495921%26oauth_version%3D1.0'
      
    hashed = hmac.new(_KEY, _BASE_STR, sha1)
    digest = hashed.digest()
    enc_digest = base64.urlsafe_b64encode(digest)
    signature = str(enc_digest, 'utf-8')
    

3. 사용자 인증 페이지 호출

Request token을 요청하면 Service provider는 Request token으로 사용할 oauth_token과 oauth_token_secret을 반환한다. token 정보는 Access token을 요청할 때 사용되므로 저장한다.

oauth_token을 매개변수로 이용자를 Service provider측 사용자 인증 페이지로 리디렉션시킨다. Callback URL을 미리 지정하여 인증을 마치면 Client로 리다이렉트시키는 경우가 많다. 이러한 경우 보통 callback url도 매개변수로 전달된다.

# 사용자 인증 페이지 URL 예시
https://api.exmaple.com/oauth/Confirm

# 리디렉션 URL 에시
https://api.exmaple.com/oauth/Confirm?oauth_token=wjeofhj28939wehiuh1&oauth_callback=localhost

4. Access token 요청

Request token 요청 과정과 거의 같으나 사용되는 매개변수와 암호화 키가 다르다.

  1. 매개변수의 종류
    • oauth_nonce
    • oauth_signature
    • oauth_signature_method
    • oauth_timestamp
    • oauth_token
    • oauth_verifier
    • oauth_version (optional)
  2. 암호화 키
    • Request token: Consumer secret
    • Access token: Consumer secret + & + oauth_token_secret

Request token과 동일한 과정으로 Signature를 생성한 뒤 Access token URL로 Access token을 요청하면 Access token으로 사용될 oauth_token과 oauth_token_secret을 전달받는다.

Access token 사용하기

이제 Access token으로 권한이 필요한 API를 호출할 수 있다. 권한이 필요한 API를 호출할 때 OAuth 매개변수를 헤더로 전달하면 된다. 헤더에 Authorization 필드를 만들고 OAuth 매개변수를 적는다. 경우에 따라 Required header가 존재할 수 있으므로 반드시 공식문서를 확인한다.

POST /questions/iamge.jpg HTTP/1.1
Authorization: OAuth oauth_consumer_key="sdkfjnwknf2fwieuo2i4",
oauth_token="yn29e328u0.103joidoadsnflsd12nwe", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1624495921", oauth_nonce="safn2uii7i31",
oauth_signature="SAdlnuoqiwh37h321="
Connection: Keep-Alive  
Host: https://api.example.com

댓글남기기