본문 바로가기

Security

[Oauth] Oauth 2.0 기본 개념 및 동작 원리

최근 인증/인가 관련 구현 및 Oauth 2.0 적용을

Java, Python, Go (예정) 에서 구현을 해 볼 기회가 있었다.

 

각각의 프로젝트에서 프론트/백 책임 분배 및 내부 인증/인가 방식이 조금씩 다르게 구현하게 되었고,

로컬 로그인과 소셜 로그인을 동시에 구현하게 된 경우도 있어, 그에 대해 글로 정리해 볼 까 한다.

 

먼저 처음 이 글에서는 Oauth 2.0 의 개념과 동작 원리를 살펴보겠다.

 

Oauth 란?

OAuth는 Client가 Resource Owner (다른 클라이언트 또는 사용자)를 대신하여 Server Resource에 액세스할 수 있는 방법을 제공한다.

사용자가 자격 증명(사용자 이름 및 비밀번호)을 공유하지 않고도 Server Resource에 대한 타사 액세스 권한을 부여할 수 있는 프로세스를 제공한다.

 

좀 더 예를 들어 설명해보자면,

Instagram에서 사진을 Facebook에 공유하고 싶을 때

 

Instagram (Client)이 사용자(Resource Owner)를 대신해서 Facebook의 "포스팅 기능"(Server Resource)에 접근할 수 있도록 방법을 제공하고,

 

Facebook 아이디와 비밀번호를 인스타그램에 직접 입력하지 않고,  Facebook 로그인 페이지에서 직접 로그인 후, 인스타그램에 권한만 부여가 가능하다는 뜻이다.

 

OAuth는 신뢰할 수 있는 중개자처럼 작동하여, 사용자의 민감한 정보는 보호하면서 필요한 기능은 안전하게 공유할 수 있게 해준다.

 

OAuth를 이용하여 소셜 로그인 (네이버, 카카오, 구글 등)을 구현하고자 하였다.

 

Oauth 용어

위의 개념에서 등장한 용어를 포함해 몇몇 자주 등장하는 용어를 알아보자.

 

1. Protected Resource (보호된 자원)

  • 인증된 사용자만 접근 가능한 데이터나 기능
  • 예시: 카카오 프로필 정보, 친구 목록, 이메일 주소

2. Resource Owner (자원 소유자)

  • Protected Resource의 실제 소유자 및 접근 권한을 부여할 수 있는 주체 (일반적으로 최종 사용자(end-user))
  • 예시: 카카오 계정을 가진 실제 사용자

3. Client

  • OAuth 인증을 사용해 Resource Owner를 대신해서  Protected Resource에 접근하는 애플리케이션
  • 예시: 카카오톡으로 배달의민족 로그인할 때, 배달의민족이 Client

4. Authorization Server (인증 서버)

  • 인증과 권한 부여를 담당하는 서버
  • Acccess Token을 발급하는 주체
  • 예시: 카카오 로그인 시스템

5. Resource Server (자원 서버)

  • Protected Resource을 실제로 가지고 있는 서버
  • 액세스 토큰을 사용한 요청을 처리
  • 예시: 카카오톡 API 서버
    • 친구목록, 프로필 등 실제 데이터를 보관
    • 유효한 액세스 토큰이 있으면 요청한 데이터 제공

 

Client - Oauth 용어

Client가 Oauth 인증을 하기 위해 필요한 정보들에 대한 용어도 알아보자.

 

1. Client ID

  • 앱을 식별하는 고유 번호 (마치 사업자 등록번호)
  • 어떤 앱이 OAuth 요청을 하는지 식별
  • Authorization Code를 Access Token으로 교환할 때 사용

2. Client Secret

  • 앱의 신원을 인증하는 비밀번호 (절대 노출되면 안 됨)
  • 앱이 진짜 등록된 앱이 맞는지 인증  
  • Authorization Code를 Access Token으로 교환할 때 사용

3. Redirection Endpoint (리다이렉션 주소)

  • Authorization Code를 전달하는 URL 통로
  • Authorization Code를 Access Token으로 교환할 때 사용

4. Scope (접근 범위)

  • 앱이 요청하는 권한의 범위
  • 예시: "profile email friends_list" 
  • 공백으로 구분된 문자열
  • 대소문자 구분 
  • 순서는 상관없음

5. State

  • csrf 보호를 위한 값 (csrf 토큰과 비슷한 동작)
  • Client가 유니크한 state 값 생성 (state 값은 1회용으로만 사용) 및 세션 저장
  • 이 값을 인증 요청에 포함 -> 인증 서버가 동일한 값 반환
  • Client가 Redirection Endpoint callback에서 state값 검증

 

Oauth 동작 원리

예시로 카카오의 로그인 과정을 가져왔다.

 

1.  Authorization Code (인가 코드) 받기

Resource Owner(사용자)가 카카오 로그인 요청을 하면,

Client (어플리케이션)Authorization Server (인증 서버)에 Client ID, Redirect Url, Scope, State 등을 쿼리 파라미터에 포함시킨 GET Request를 보내게 된다.

https://kauth.kakao.com/oauth/authorize?
response_type=code
&client_id=${REST_API_KEY}
&redirect_uri=${REDIRECT_URI}
&scope=${SCOPE}
&state=${STATE}

 

올바른 Request라면 Authorization Server가 로그인 할 수 있는 페이지를 제공해 준다.

 

그 후,  Resource Owner가 ID/Password를 입력하면, Authorization Server에서 일치 여부를 확인 한 후,

Client가 사용하려는 Resource Server의  Protected Resource (보호 자원)의 공유 Scope에 사용을 동의하는지, Resource Owner의 동의를 요청하는 페이지를 제공한다.

 

이용내역에 동의를 한다면, Resource OwnerClient권한을 위임했다는 승인이 Authorization Server에 전달된다.

그러면 HTTP 302 리다이렉트되어, Redirect URIGET 요청으로 전달하게 된다.

HTTP/1.1 302 Found
Content-Length: 0
Location: ${REDIRECT_URI}?code=${AUTHORIZE_CODE}&state=${STATE}

 

여기서 Client는 요청할 때 임의로 생성한 State와 응답받은 State를 검증하여 CSRF 공격을 방지 할 수 있다.

 

2.  토큰 받기

Authorization CodeResource Owner Client 권한을 위임했다 라는 정보일 뿐,

Authorization Server에서 Client검증이 필요하고, 검증이 완료되면 Access Token을 받을 수 있다.

 

Access Token을 발급받기 위해 Clientclient_id, redirect_uri, code, client_secret 등을 포함하여 POST Request를 보낸다.

curl -v -X POST "https://kauth.kakao.com/oauth/token" \
    -H "Content-Type: application/x-www-form-urlencoded;charset=utf-8" \
    -d "grant_type=authorization_code" \
    -d "client_id=${REST_API_KEY}" \
    --data-urlencode "redirect_uri=${REDIRECT_URI}" \
    -d "code=${AUTHORIZE_CODE}"

 

Authorization Server 에서 Client 검증이 완료된다면, Access TokenRefresh Token을 발급해 주게 된다.

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
    "token_type":"bearer",
    "access_token":"${ACCESS_TOKEN}",
    "expires_in":43199,
    "refresh_token":"${REFRESH_TOKEN}",
    "refresh_token_expires_in":5184000,
    "scope":"account_email profile"
}

 

3.  사용자 로그인 처리

그림에서 생략되었지만, 

위에서 받은 Access Token으로 Resource Server에 유저 정보를 얻어오는 API를 호출해서 유저 정보를 얻어온 후,

Client 내부에서 회원가입 처리를 하거나 JWT 토큰을 발급하는 등 로그인 처리를 한다.

 

이 단계는 나중에 Java 프로젝트에서 적용 예시에 대한 글을 작성 할 때 알아보도록 하자.

 

 

 

다음 글에서는 위의 Oauth 동작 원리에서 프론트/백 에서 어느 부분까지 처리할 지에대한 내용을 다뤄보고,

Client에서 사용한 내부 인증/인가 방법 (JWT, Session) 에 대한 내용을 다룰 것이다.

 

<Reference>

https://datatracker.ietf.org/doc/html/rfc6749

 

RFC 6749: The OAuth 2.0 Authorization Framework

The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowi

datatracker.ietf.org

https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-OAuth-20-%EA%B0%9C%EB%85%90-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC

 

🌐 OAuth 2.0 개념 - 그림으로 이해하기 쉽게 설명

OAuth란? 웹 서핑을 하다 보면 Google과 Facebook 등의 외부 소셜 계정을 기반으로 간편히 회원가입 및 로그인할 수 있는 웹 어플리케이션을 쉽게 찾아볼 수 있다. 클릭 한 번으로 간편하게 로그인할

inpa.tistory.com