[OAuth 2.0] 5. Issuing an Access Token

액세스 토큰 요청이 유효하고 인가 된 경우

  • 인가 서버는 5.1절에 설명된 것과 같이 액세스 토큰과 선택적으로 리프레시 토큰을 발급함
  • 요청에서 클라이언트 인증이 실패했거나 요청이 유효하지 않은 경우 인가 서버는 5.2절에 설명된 바와 같이 오류 응답을 반환

5.1 성공 응답

인가 서버는 액세스 토큰과 선택적으로 리프레시 토큰을 발급

 

HTTP 응답의 엔티티 본문(entity-body)에 다음 매개변수들을 추가하여 200(OK) 상태 코드의 응답을 구성

 

  • access_token
    • 필수(REQUIRED). 인가 서버에 의해 발급된 액세스 토큰.
  • token_type
    • 필수(REQUIRED). 7.1절에 설명된 바와 같이 발급된 토큰의 유형. 값은 대소문자를 구분하지 않는다.
  • expires_in
    • 권장(RECOMMENDED). 액세스 토큰의 수명(초 단위). 예를 들어 값 “3600”은 응답이 생성된 시점으로부터 액세스 토큰이 1시간 후에 만료됨을 의미한다. 이 값이 생략된 경우, 인가 서버는 다른 수단을 통해 만료 시간을 제공하거나 기본값을 문서화하는 것이 바람직하다(SHOULD).
  • refresh_token
    • 선택(OPTIONAL). 6절에 설명된 바와 같이, 동일한 인가 그랜트를 사용하여 새로운 액세스 토큰을 획득하는 데 사용할 수 있는 리프레시 토큰.
  • scope
    • 클라이언트가 요청한 범위(scope)와 동일한 경우 선택(OPTIONAL)이며, 그렇지 않은 경우 필수(REQUIRED). 3.3절에 설명된 액세스 토큰의 범위.

 

이 매개변수들은 [RFC4627]에 정의된 "application/json" 미디어 타입을 사용하여 HTTP 응답의 엔터티 본문에 포함된다.

 

각 매개변수는 최상위 구조 수준에 추가함으로써 JavaScript Object Notation(JSON) 구조로 직렬화된다.

 

매개변수 이름과 문자열 값은 JSON 문자열로 포함되며, 숫자 값은 JSON 숫자로 포함된다. 매개변수의 순서는 중요하지 않으며 달라질 수 있다.

 

인가 서버는 토큰, 자격 증명 또는 기타 민감한 정보를 포함하는 모든 응답에 대해, 값이 "no-store"인 HTTP "Cache-Control" 응답 헤더 필드[RFC2616]와, 값이 "no-cache"인 "Pragma" 응답 헤더 필드[RFC2616]를 반드시 포함해야 한다(MUST).

Content-Type : HTTP 응답 본문(body)의 형식이 무엇인지 알려주는 헤더
- 밑 예시에 있는 것의 의미는 이 응답 본문은 JSON 형식, 문자 인코딩은 UTF-8
- 왜 필요하냐면 OAuth 토큰 응답은 JSON임 클라이언트가 이걸 JSON으로 정확히 파싱하려면 Cotent-Type이 반드시 필요
Cache-Control : HTTP 캐싱(브라우저, 프록시, CDN 등)에 대한 강제 규칙을 지정하는 헤더
- 밑 예시 의미는 절대 저장하지 마라 디스크, 메모리, 중간 프록시 어디에도 캐싱 금지
- OAuth에서 왜 중요하나면 OAuth 응답에는 치명적으로 민감한 정보인 액세스 토큰, 리프레시 토큰, 클라이언트 식별자 등이 있음 만약 캐시되면 다른 사용자에게 노출되거나 브라우저 히스토리 디스크에 남음, 프록시 서버에 저장된다. 
Pragma : HTTP/1.0 시대의 구형 캐시 제어 헤더 
- Cache-Control이 있으면 필요 없다고 생각할 수 있음 하지만 현실은 오래된 브라우저, 오래된 프록시 서버, HTTP/1.0 기반 캐시 이런 애들은 Cache-COntrol을 무시할 수 있음 그래서 이중 안전장치로 하는 것

 

예를 들면 다음과 같다.

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
  "access_token":"2YotnFZFEjr1zCsicMWpAA",
  "token_type":"example",
  "expires_in":3600,
  "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
  "example_parameter":"example_value"
}

 

클라이언트는

  • 응답에 포함된 인식하지 못하는 값 이름을 무시해야 한다(MUST).
  • 인가 서버로부터 수신하는 토큰 및 기타 값들의 크기는 본 명세에서 정의되지 않는다. 클라이언트는 값의 크기에 대해 가정을 피해야 한다. 인가 서버는 자신이 발급하는 모든 값의 크기를 문서화하는 것이 바람직하다(SHOULD).

 

5.2 오류 응답

인가 서버는 (달리 명시되지 않는 한) HTTP 400(Bad Request) 상태 코드로 응답하며, 응답에 다음 매개변수들을 포함한다:

 

error 필수(REQUIRED). 다음 중 하나의 단일 ASCII [USASCII] 오류 코드:

  • invalid_request
    • 요청에 필수 매개변수가 누락되었거나, (그랜트 타입을 제외한) 지원되지 않는 매개변수 값이 포함되었거나, 매개변수가 반복되었거나, 여러 자격 증명이 포함되었거나, 클라이언트 인증을 위해 하나 이상의 메커니즘을 사용했거나, 그 밖에 요청 형식이 잘못된 경우.
  • invalid_client
    • 클라이언트 인증이 실패한 경우(예: 알 수 없는 클라이언트, 클라이언트 인증이 포함되지 않은 경우, 또는 지원되지 않는 인증 방식). 인가 서버는 어떤 HTTP 인증 방식이 지원되는지를 나타내기 위해 HTTP 401(Unauthorized) 상태 코드를 반환할 수 있다(MAY). 클라이언트가 "Authorization" 요청 헤더 필드를 통해 인증을 시도한 경우, 인가 서버는 반드시 HTTP 401(Unauthorized) 상태 코드로 응답해야 하며(MUST), 클라이언트가 사용한 인증 방식과 일치하는 "WWW-Authenticate" 응답 헤더 필드를 포함해야 한다.
  • invalid_grant
    • 제공된 인가 그랜트(예: 인가 코드, 리소스 소유자 자격 증명) 또는 리프레시 토큰이 유효하지 않거나, 만료되었거나, 철회되었거나, 인가 요청에서 사용된 리다이렉션 URI와 일치하지 않거나, 다른 클라이언트에 발급된 경우.
  • unauthorized_client
    • 인증된 클라이언트가 이 인가 그랜트 유형을 사용할 권한이 없는 경우.
  • unsupported_grant_type
    • 인가 서버가 해당 인가 그랜트 유형을 지원하지 않는 경우.
  • invalid_scope
    • 요청된 범위(scope)가 유효하지 않거나, 알 수 없거나, 형식이 잘못되었거나, 리소스 소유자가 부여한 범위를 초과한 경우.

 

"error" 매개변수의 값에는 %x20-21 / %x23-5B / %x5D-7E 집합에 포함되지 않은 문자가 포함되어서는 안 된다(MUST NOT

 

  • error_description
    • 선택(OPTIONAL). 발생한 오류를 이해하는 데 도움을 주기 위해 클라이언트 개발자를 보조하는, 사람이 읽을 수 있는 ASCII [USASCII] 텍스트 형태의 추가 정보. "error_description" 매개변수의 값에는 %x20-21 / %x23-5B / %x5D-7E 집합에 포함되지 않은 문자가 포함되어서는 안 된다(MUST NOT).
  • error_uri
    • 선택(OPTIONAL). 오류에 대한 정보를 포함한 사람이 읽을 수 있는 웹 페이지를 식별하는 URI로, 클라이언트 개발자에게 오류에 대한 추가 정보를 제공하는 데 사용된다. "error_uri" 매개변수의 값은 URI-reference 구문을 따라야 하며, 따라서 %x21 / %x23-5B / %x5D-7E 집합에 포함되지 않은 문자를 포함해서는 안 된다(MUST NOT).

 

-> error_description, error_uri는 다음과 같이 쓸 수 있음

{
  "error": "invalid_grant",
  "error_description": "Authorization code has expired"
}

 

이 매개변수들은 [RFC4627]에 정의된 "application/json" 미디어 타입을 사용하여 HTTP 응답의 엔터티 본문에 포함된다.

 

각 매개변수는 최상위 구조 수준에 추가함으로써 JSON 구조로 직렬화된다.

 

매개변수 이름과 문자열 값은 JSON 문자열로 포함되며, 숫자 값은 JSON 숫자로 포함된다. 매개변수의 순서는 중요하지 않으며 달라질 수 있다.

 

HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
  "error":"invalid_request"
}