본문 바로가기
Backend/인증

[인증] OAuth 2.0 (개념 정리)

by WooHey 2022. 10. 22.

소개

OAuth 2.0 은 인증을 위한 개방형 표준 프로토콜이다.
Resource Owner(사용자) 를 대신해서 Resource Server 에서 제공하는 자원에 대한 접근 권한을 위임하는 방식을 제공한다.
대표적인 예로, Google, Facebook(현 Meta), Twitter, 국내 기업으로는 Kakao, Naver 등의 플랫폼에서 제공하는 간편 로그인 기능도 OAuth 2.0 프로토콜 기반으로 사용자 인증 기능을 제공하고 있다.

Flow

kakao 로그인 예시 (출처: 카카오 로그인)
여기서 Service Client 는 Resource Owner(사용자), Service Server 는 Client(Application) 이라고 생각하면 된다.

OAuth 2.0 주요 용어

  • Authentication (인증)
    • 접근 자격이 있는지 검증
  • Authorization (인가)
    • 자원에 접근할 수 있는 권한을 부여하는 것
  • Access token
    • Resource Server 에서 Resource Owner(사용자) 의 보호된 자원을 획득할 때 사용되는 token.
  • Refresh token
    • Access token 의 사용 기한이 만료되었을 때 Access token 을 갱신하기 위한 용도로 사용하는 token.

매개변수

Authorization Server 로 인증 또는 인가 요청 및 응답 시에 사용되는 Parameter 이다.

Authorization Request

  • response_type
    • 실행할 권한 부여 서버를 알려준다.
    • Authorization Code Grant 방식에서 요구하는 Authorization code 를 요청하기 위해서는 response_type = code 로 전달.
    • Implicit Grant 방식에서 요구하는 Access token 을 요청하기 위해서는 response_type = token 로 전달.
  • redirect_uri
    • Authorization Server 는 Resource Owner(사용자) 와의 상호 작용(예: "xx 서비스(Client)가 사용자의 구글 계정에 접근하려합니다." 와 같은 화면) 을 완료한 후 Resource Owner(사용자) 의 User Agent 를 Client(Application) 로 다시 보낸다.
    • 즉, 성공 응답 시에 request 시 전달 받았던 redirect_uri 로 다시 응답을 보낸다.
  • client_id (Client 등록 시 발급)
    • 승인을 요청하는 애플리케이션의 ID 값.
    • Resource Server 를 이용하기 위해 Resource Server 에 Client 를 등록 시 발급해준다.
  • scope
    • Client 가 사용 할(가능한) 기능 목록.
    • 예: 구글 이메일, 연락처 등
  • state
    • Client 의 request 와 그에 따른 callback 사이의 상태를 유지하기 위해 Client 에서 사용하는 opaque value 이다. 즉, Application 의 이전 상태를 복원할 수 있도록 해주는 매개변수이다.
    • 초기 인증 요청 중 Client 에서 Authorization Server 로 전송되고, Authorization Server 는 code 와 함께 client 로 다시 전송된다. client 는 이 "state" 의 내용을 사용하여 수신한 code 가 전송한 인증 요청과 일치하는지 확인해야 한다.
    • 주된 목적은 Cross-site request forgery(CSRF) 를 방지하기 위해 사용한다.

Authorization Response

  • code
    • Authorization Server 에 의해 생성된 authorization code(인증 코드) 이다.
    • 최대 인증 코드(code)의 수명은 10분을 권장하며, Client 는 이 인증 코드(code) 를 2번 이상 사용해서는 안된다. 같은 인증 코드(code) 가 2번 이상 사용되는 경우, Authorization Server 는 request 를 거부해야 하며 해당 인증 코드(code) 를 기반으로 이전에 발급된 모든 token (가능한 경우)을 취소해야 한다.
    • 인증 코드(code) 는 Client ID 및 redirection URL 에 바인딩 된다.
  • state
    • state매개변수가 Client 의 Authorization Request 에 있는 경우에 필수이다.

Access token Request

  • grant_type
    • Access Token 획득 요청 시 포함되는 값으로 권한 부여 방식에 대한 설정이다. 아래 값 중 한 개를 사용한다.
      • authorization_code : Authorization Code Grant
      • password : Resource Owner Password Credentials Grant
      • client_credentials : Client Credentials Grant
  • code
    • Authorization Server 로 부터 받은 authorization code(= code) 값.
  • redirect_uri
    • 위에서 설명한 Authorization Endpoints 의 redirect URL 이다.
    • "redirect_uri" 매개변수가 AUthorization Request 에 포함되어 있고, 그 값이 동일해야 한다.
  • client_id
    • 승인을 요청하는 Client(Application) 의 ID 이다.
    • Client 등록 시 발급 받은 Client ID 값.
  • username
    • Resource Owner 의 username
  • password
    • Resource Owner 의 password
  • scope
    • Client 가 사용 할(가능한) 기능 목록.
    • 예: 구글 이메일, 연락처 등

Role | 역할

Resource Owner

리소스 소유자(사용자)를 말한다. 보호된 자원에 접근할 수 있는 자격을 부여해주는 주체이다. OAuth 프로토콜 흐름에서 Client 가 Resource Server 로 부터 Resource 접근 권한을 부여할 수 있도록 중개 역할을 한다.

Client

Resource Server 에 저장된 Resource Owner(사용자) 의 보호된 자원을 사용하기 위해 접근 요청을 하는 Application 이다. 일반적으로 Client 는 사용자를 일컫기도 하지만, 여기서의 Client 는 Resource Server 의 관점에서 third-party Application 을 말한다.

Resource Server

Resource Owner(사용자) 의 보호된 자원을 호스팅하는 Server 이다.

Authorization Server

Authentication, Authorization 을 수행하는 Server 로, Client 의 접근 자격을 확인하고, Access token 을 발급하여 Resource Owner 의 자원에 접근할 수 있는 권한을 부여하는 역할을 수행한다.

Endpoints

OAuth 2.0 은 /authorize 라는 Endpoint 와 /oauth/token 이라는 두 가지의 Endpoint 를 사용한다.

Authorization Endpoint

Authorization Endpoint 는 Resource Owner 와 상호작용 하고 보호된 리소스에 접근할 수 있는 권한을 얻는데 사용된다.
예를 들어, Google 계정을 이용해 타 Service 또는 플랫폼에 로그인하려 할 때, 먼저 Service 가 인증을 위해 Google 로 redirecion 한 후(아직 사용자는 구글 계정 로그인을 하지 않음), 동의 화면이 표시된다. 동의 화면에는 서비스가 Resource Owner(사용자)의 보호된 리소스에 접근할 수 있도록 승인하라는 메시지가 표시된다. (예: 구글 이메일, 연락처 등)

Client 는 "application/x-www-form-urlencoded" 형식을 사용하여 Authorization endpoint URI의 쿼리 구성 요소에 매개 변수를 추가하여 요청 URI를 구성한다.

Token Endpoint

Token Endpoint 는 Access token 또는 refresh token 을 얻기 위해 Client(Application) 에서 사용된다.
아래의 Grant type 중 Implicit Grant(암시적 승인) 방식을 제외한 모든 방식에서 사용된다.

Grant type 권한 부여 방식

OAuth 2.0 프로토콜 에서는 다양한 Client 환경에 적합하도록 권한 부여 방식에 따른 프로토콜을 4가지 종류로 구분하여 제공하고 있다.

1. Authorization Code Grant | 인증 코드 부여 방식

권한 부여 승인을 위해 자체 생성한 Authorization Code 를 전달하는 방식으로, OAuth 2.0 프로토콜에서 가장 기본적으로 쓰인다.
Client 가 Resource Owner(사용자) 를 대신하여 사용자의 특정 자원에 접근을 요청할 때 사용되는 방식이다.
Refresh token 사용이 가능하다.

Authorization Request

# request Example

GET /authorize?
    response_type=code
    &client_id=s6BhdRkqt3
    &state=xyz
    &redirect_uri=https://client.Eexample.com. HTTP/1.1
Host: server.example.com

/authorize 의 매개변수는 아래와 같다.

  • (필수) response_type
    • response_type = code 로 요청해야 한다.
  • (선택) redirect_uri
  • (필수) client_id
  • (선택) scope
  • (선택)(추천) state

Authorization Response

# response Example

HTTP/1.1 302 Found
Location: 
    https://client.example.com/cb
    ?code=SplxlOBeZQQYbYS6WxSbIA
    &state=xyz
  • (필수) code
  • (필수) state

Access token Request

# Access token Request Example

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https://client.example.com/

/token 의 매개변수는 아래와 같다.

  • (필수) grant_type
    • grant_type = authorization_code 로 요청해야 한다.
  • (필수) code
  • (필수) redirect_uri
  • (필수) client_id

Access token response

# Access token Response Example

 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"
 }

2. Implicit Grant | 암시적 승인 방식

Implicit Grant 방식은 Access token(Refresh token 을 지원하지 않음)을 얻기 위해 사용되는 방식이다. 일반적으로 자격 증명을 안전하게 저장하기 힘든 JavaScript와 같은 스크립트 언어를 사용하는 브라우저에서 구현된다.
권한 부여 요청과 Access token 발급 요청을 별도로 요청하는 Authorization Code Grant 방식과 달리, Implicit Grant 방식은 권한 부여 요청의 결과로 Access token 을 수신한다.
Refresh token 사용이 불가능하다.

Implicit Grant 방식에서 중요한 점은 Authorization Request (인증 요청) 을 통해서 받는 Response 가 Access token 이라는 점이다. 때문에 Access token Reqeust & Response 가 없다.

Authorization Request

# Example

GET /authorize?
    response_type=token
    &client_id=s6BhdRkqt3
    &state=xyz
    &redirect_uri=https://client.Eexample.com/ 
HTTP/1.1
    Host: server.example.com

/authorize 의 매개변수는 아래와 같다.

  • (필수) response_type
    • response_type=token 로 요청해야 한다.
  • (필수) client_id
  • (선택) redirect_uri
  • (선택) scope
  • (선택)(추천) state

Access token Response

Resource Owner 가 access 요청을 승인하면, Authorization Server 는 Access token 을 발급해서 Client 에게 전달한다.

# Example

HTTP/1.1 302 Found
Location:
    http://example.com/cb#
        access_token=2YotnFZFEjr1zCsicMWpAA
        &state=xyz
        &token_type=example
        &expires_in=3600

3. Resource Owner Password Credentials Grant | 자원 소유자 자격 증명 승인 방식

Resource Owner Password Credentials Grant 방식은 Resource Owner 가 Client 와 신뢰 관계를 맺고 있는 경우에 적합하다.
username, password 로 Access token 을 발급 받는 방식이기 때문에 Resource Owner 와 Client 가 신뢰할 수 없는 관계(타사의 외부 Application)라면 이 방식은 사용해서는 안된다.
Refresh token 사용이 가능하다.

Authorization Request & Response

Client 가 Resource Owner 자격 증명을 얻는 방법은 이 규격의 범위를 벗어난다.
Access token 을 얻은 후에는 Client 가 자격 증명을 삭제해야 한다.

Access token Request

# Example

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=password&username=johndoe&password=A3ddj3w

/token 의 매개변수는 아래와 같다.

  • (필수) grant_type
    • grant_type=password 로 요청해야 한다.
  • (필수) username
  • (필수) password
  • (선택) scope

Access token Response

# Example

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"
}

4. Client Credentials Grant | 클라이언트 자격 증명 승인 방식

Client 자격 증명 만으로 Access token 을 획득하는 방식이다.
Client 의 제어 하에 있는 보호된 리소스에 대한 접근을 요청하는 경우 또는 Authorization Server 에 다른 Resource Owner 의 자격 증명을 사용하여 Access token 을 요청하는 방식이다.
이 방식은 반드시 신뢰받는 Client 에서만 사용해야 한다.
OAuth 2.0 권한 부여 방식 중 가장 간단한 방식으로, Client 자신이 관리하는 Resource 혹은 Authorization Server 에 해당 Client 를 위한 제한된 Resource 접근 권한이 설정되어 있는 경우에 사용한다.
Refresh token 사용이 불가능하다.

Authorization Request & Response

Client 인증을 권한 부여로 사용하므로 추가 인증 요청이 필요하지 않다.

Access token Request

# Example

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials

/token 의 매개변수는 아래와 같다.

  • (필수) grant_type
    • grant_type = client_credentials 로 설정한다.
  • (선택) scope

Access token Response

# Example 

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,
    "example_parameter":"example_value"
}

Refreshing an Access token

# Example

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA

/token 의 매개변수는 아래와 같다.

  • (필수) grant_type
    • grant_type=refreshtoken 으로 설정해야 한다.
  • (필수) refresh_token
    • Client 에게 발급된 Refresh token 이다.
  • (선택) scope

참고