OAuth, OIDC (1)

Jayven·2024년 9월 13일

Computer Science

목록 보기
3/6

안녕하세요 제이븐입니다 🙇

이번 포스팅은 모바일 애플리케이션 개발에서 보안, 인증(Authentication), 인가(Authorization)를 처리하는 핵심 기술인 OAuth, OIDC에 대해서 알아보겠습니다!


OAuth 와 OIDC의 등장 배경


OAuth와 OIDC가 등장하기 전에는 각 서비스가 사용자 데이터를 직접 관리하는 경우가 대부분이었습니다.
그러나 이러한 방식은 해킹 등의 문제로 개인정보 유출이 자주 발생하여, 서비스 제공자가 직접 관리하는 것에 대한 부담이 점점 커졌습니다.

또한, 모든 서비스가 각각의 인증 시스템을 운영하면, 사용자는 사용하는 서비스마다 서로 다른 인증 정보를 기억해야 하는 불편함이 생깁니다.

이를 해결하기 위해, 구글이나 페이스북과 같은 신뢰할 수 있는 웹사이트에 사용자 인증 절차를 위임하고,
사용자는 하나의 인증 정보만으로 여러 서비스를 안전하게 로그인할 수 있는 방법이 등장했습니다.
이것이 바로 OAuth와 그 위에서 동작하는 OIDC(OpenID Connect)입니다.

OAuth는 Authorization(인가)를 초점으로, OIDC는 Authentication(인증)을 초점으로 합니다.
이 둘은 비슷하지만, 다루는 관심사가 다릅니다.

다음으로, OAuth와 OIDC가 무엇인지, 그리고 인증과 인가가 어떻게 다른지 알아보겠습니다.


OAuth란?


웹사이트나 앱에서 로그인 또는 회원가입을 할 때
Goole, Naver, Kakao, Apple, FaceBook 등의 외부 소셜 계정을 이용해 간편하게 회원가입 및 로그인을 할 수 있는 경우를 자주 볼 수 있습니다.

이러한 소셜 로그인은 클릭 한 번으로 간단하게 회원가입이나 로그인을 할 수 있을 뿐만 아니라,
해당 플랫폼에서 제공하는 다양한 기능을 손쉽게 사용할 수 있는 장점이 있습니다.

OAuth는 이러한 다양한 플랫폼에서 특정한 사용자 데이터에 접근하기 위해 클라이언트(서비스 앱, 웹)가
사용자의 접근 권한을 인가(Authorization) 받을 수 있도록 해주는 표준 프로토콜입니다.


OAuth 정의

OAuth는 Open Authorization의 약자입니다.
사용자들이 로그인 자격 증명(비밀번호 입력)을 제공하지 않고도,
해당 애플리케이션이 특정 리소스에 접근할 수 있도록 권한을 위임하는 표준 프로토콜입니다.


OAuth의 구성요소


리소스 소유자 (Resource Owner)

리소스를 소유한 사용자로, 서비스를 이용하려는 주체입니다.
쉽게 말해, 앱이나 웹사이트를 이용하고자 하는 사용자가 리소스 소유자입니다.

"리소스"는 사용자와 관련된 다양한 데이터나 서비스에 접근할 수 있는 모든 자원을 의미합니다.


클라이언트 (Client)

리소스 소유자의 리소스에 접근하려는 애플리케이션입니다.
이 클라이언트는 보통 회사나 개인이 만든 앱이나 웹서비스를 의미합니다.

예를 들어, 어떤 앱이 사용자의 구글 계정 정보에 접근하려고 한다면,
그 앱이 클라이언트로서 리소스 서버에 요청을 보내는 주체가 됩니다.


리소스 서버 (Resource Server)

리소스 서버는 사용자의 리소스(데이터)를 저장하고 있는 서버입니다.
구글, 카카오, 네이버와 같은 서비스가 리소스 서버의 예입니다.

리소스 서버는 토큰을 기반으로 사용자의 리소스에 대한 접근을 허용합니다.
클라이언트가 액세스 토큰을 사용해 리소스 서버에 접근 요청을 보내면, 해당 토큰이 유효한 경우 요청된 리소스를 반환합니다.


인증 서버 (Authorization Server)

인증 서버는 클라이언트가 리소스 서버에 접근할 수 있는 권한을 부여하는 서버입니다.
이 서버는 액세스 토큰과 리프레시 토큰을 발급합니다.

사용자는 인증 서버를 통해 인증을 거쳐 Authorization Code를 발급받고,
클라이언트는 이를 사용해 토큰을 발급받아 리소스 서버에 접근할 수 있습니다.


액세스 토큰 (Access Token)

액세스 토큰은 클라이언트가 리소스 서버에 접근할 수 있도록 인증 서버에서 발급된 토큰입니다.
클라이언트는 이 토큰을 사용해 리소스 서버에 요청을 보냅니다.


리프레시 토큰 (Refresh Token)

리프레시 토큰은 액세스 토큰의 유효 기간이 만료되었을 때, 새로운 액세스 토큰을 발급받기 위해 사용되는 토큰입니다.
액세스 토큰은 보안을 위해 만료 기간이 짧기 때문에, 클라이언트는 리프레시 토큰을 사용해 새로운 액세스 토큰을 발급받아 다시 리소스 서버에 접근할 수 있습니다.


OAuth 프로세스

1. 로그인 시도, 리다이렉션

Resource Owner -> Client -> Authoriazation Server
사용자가 클라이언트 애플리케이션(예: 특정 웹사이트나 앱)에 로그인하려고 시도하면,
클라이언트는 Authorization Server(인증 서버)에 인증 요청을 보냅니다.

클라이언트는 사용자를 Authorization Server로 리다이렉트합니다.
이 과정에서 클라이언트는 Authorization URL을 생성하여, 사용자를 인증 서버로 안내합니다.
요청은 URL을 통해 이루어지며, 요청에 필요한 정보는 URL의 쿼리 파라미터로 전달됩니다.

쿼리 파라미터에 포함되는 정보

  • response_type
    클라이언트가 인증 서버로부터 받기를 원하는 응답의 유형
  • client_id
    클라이언트 애플리케이션을 식별하는 고유한 ID.
  • redirect_uri
    인증이 성공하거나 실패했을 때 사용자를 리다이렉트할 클라이언트 애플리케이션의 URL.
  • scope
    클라이언트가 요청하는 자원의 범위(예: 사용자 프로필, 이메일 등).
  • state
    CSRF 공격을 방지하고 요청의 무결성을 확인하기 위한 임의의 문자열. 인증 후 이 값을 그대로 돌려받아 클라이언트는 요청의 일관성을 확인할 수 있습니다.

2. 로그인 페이지 제공

Authrization Server -> Resource Owner
소셜 서비스(예: 구글)에서 사용자가 자격증명을 입력할 수 있는 로그인 페이지를 제공하고, 사용자가 인증 정보를 입력할 수 있습니다.

3. 로그인

Resource Owner -> Authrization Server
사용자가 소셜 서비스에서 로그인에 성공하면, 소셜 서비스는 클라이언트에게 인증을 완료했음을 알립니다.

4. Authorization Code 발급

Authrization Server -> Resource Owner
사용자가 인증에 성공하면, 소셜 서비스는 Authorization Code를 발급합니다.

5. Client에게 Code 전달

Resource Owner -> Client
발급 받은 Authorization Code를 클라이언트에게 전달합니다.

6. Token 발급

Client <-> Authrization Server
클라이언트 애플리케이션은 발급받은 Authorization Code를 인증 서버(Authorization Server)에 전달하고,
Access Token과 Refresh Token을 발급받습니다.

7. Token 저장

Client
클라이언트 애플리케이션은 받은 Access Token과 Refresh Token을 안전하게 저장합니다.

8. 인증 완료

Resource Owner -> Client
클라이언트는 인증 서버로부터 받은 Access Token을 이용해, 사용자가 성공적으로 인증되었음을 확인합니다.

9. 서비스 요청

Resource Owner -> Client -> Resource Server
클라이언트 애플리케이션은 발급받은 Access Token을 사용하여 리소스 서버(예: 구글 API)로 사용자의 데이터를 요청합니다.

10. 토큰 검증 및 응답 제공

Resource Server -> Client -> Resource Owner
리소스 서버는 Access Token을 검증하고, 요청된 데이터를 클라이언트 애플리케이션에 반환합니다.


Authorization Code를 사용하는 이유

Authorization Code 없이 바로 토큰(Token)을 받는 방식도 가능할 것 같은데, 왜 중간에 Authorization Code를 발급받는 과정이 필요할까요?

만약 Authorization Code 없이 인증 서버가 토큰을 바로 클라이언트에게 전달한다면,
토큰이 Redirect URI를 통해 URL에 포함되어 전달될 수 있습니다.
그러나 URL에 토큰이 포함되면, 네트워크를 통해 전송되는 과정에서 노출될 위험이 있습니다.

이를 방지하기 위해 Authorization Code를 중간 단계로 사용합니다.
클라이언트는 우선 Authorization Code를 받고, 이 코드를 서버 측에서 안전하게 처리하여 백엔드에서 직접 인증 서버에 토큰을 요청합니다.
이 과정을 통해 토큰이 브라우저나 URL에 노출되는 위험을 줄이고, 보안을 강화할 수 있습니다.


OAuth의 문제와 한계

OAuth 인터페이스에는 유저 정보에 대한 표준 프로토콜이 없기 때문에
외부 소셜 서비스마다 유저 데이터를 다른 방식으로 넘겨줍니다.
그래서 넘겨 받은 인터페이스에 따라 각각 대응해야된다는 문제점이 있습니다.

이러한 문제는 서비스마다 구현 방식이 다르기 때문에 일관된 사용자 정보 처리가 어려워질 수 있다는 점에서 큰 한계로 작용합니다.


OIDC(OpenID Connect)


OIDC는 OpenID Connect의 약자로, OpenID에서 추진하는 인증(Authentication) 프로토콜입니다.
OIDC는 OAuth 2.0을 기반으로 동작하며, 사용자 인증을 처리하는 데 초점을 맞추고 있습니다.

OAuth 2.0 프레임워크는 애플리케이션에 승인된 사용자에 대한 정보를 명시적으로 제공하지 않고, 대신 액세스 토큰(Access Token) 형태로 권한을 부여합니다.
액세스 토큰은 마치 호텔 키 카드와 같습니다. 호텔 키 카드를 통해 특정 객실에 출입할 권한이 있음을 알 수 있지만, 그 카드가 누구의 것인지, 소유자의 신원 정보는 알 수 없습니다.

반면, OpenID Connect(OIDC)의 주요 목적은 인증(Authentication) 입니다.
OIDC를 사용하면, 클라이언트는 ID 토큰을 획득할 수 있습니다. 이 ID 토큰에는 사용자의 신원 정보가 담겨 있습니다.
액세스 토큰이 호텔 키 카드라면, ID 토큰은 주민등록증과 같습니다.
주민등록증을 통해 사용자의 이름, 사진, 거주지와 같은 신원 정보를 확인할 수 있지만, 호텔 객실 출입 권한은 없습니다.

정리하자면, OAuth 2.0은 리소스 서버로부터 리소스를 가져오기 위한 액세스 토큰을 확보하는 데 목적이 있고, OpenID Connect는 사용자의 신원 정보가 담긴 ID 토큰을 확보하는 데 목적이 있습니다.

ID 토큰은 사용자의 정보를 담고 있는 JWT(보안 토큰 형식)이며, 이를 통해 클라이언트는 사용자가 누구인지 확인할 수 있습니다.

OAuth로는 인증이 불가능한가??

OAuth 2.0은 사용자가 소유한 리소스에 접근하기 위한 권한 부여 프로토콜입니다. 이 과정에서 인증 서버를 통해 사용자의 신원을 확인하는 단계가 포함되지만, 사용자 인증 자체를 위한 프로토콜로 설계된 것은 아닙니다.

물론, OAuth 2.0만으로도 사용자 프로필 정보를 리소스 서버에서 가져올 수 있습니다. 액세스 토큰을 발급받고, 이를 사용해 사용자 정보 리소스에 접근하는 방식으로 가능합니다.

그러나 OIDC 없이 OAuth 2.0만으로 사용자 정보를 가져오는 경우, 추가적인 통신이 필요합니다. OAuth 2.0 단독으로 사용할 경우, 액세스 토큰을 발급받은 후에 다시 해당 토큰을 사용해 사용자 리소스를 요청해야 합니다. 반면, OIDC를 사용하면 ID 토큰을 통해 한 번의 통신으로 사용자 정보를 확인할 수 있습니다.

예를 들어, OAuth 2.0만을 사용해 1억 회의 통신을 해야 한다면, OIDC를 사용하면 동일한 요청을 5천만 회로 줄일 수 있습니다. 이는 OIDC가 사용자 인증을 보다 효율적으로 처리할 수 있도록 설계되었기 때문입니다.


OICD의 주체

IdP (Identity Provider, 신원 제공자)

Identity Provider(IdP)는 신원 제공자로, 사용자(엔드유저)의 신원을 확인하고, 이를 바탕으로 클라이언트에게 ID 토큰을 발급하는 역할을 합니다.
IdP는 사용자가 신뢰하는 서비스로, 사용자의 계정 정보와 신원 데이터를 안전하게 관리하고 인증 요청을 처리합니다. 구글, 페이스북, 카카오, 네이버와 같은 서비스들이 IdP 역할을 합니다.

RP (Relying Party, 클라이언트)

Relying Party(RP)는 클라이언트 애플리케이션을 의미하며, 사용자의 신원 정보를 확인하고자 IdP로부터 ID 토큰을 받는 역할을 합니다.
RP는 사용자가 접근하려는 웹 애플리케이션이나 모바일 애플리케이션으로, 사용자가 IdP에 로그인한 후 발급된 ID 토큰을 사용하여 인증된 사용자의 신원 정보를 확인합니다.


마무리


소셜 로그인 관련해서 공부를하다가 OAuth, OICD, JWT등 개념이 등장해서
관련된 개념을 한번 정리하고자 포스팅을 하게 되었습니다.

평소에는 윤곽만 알고 사용했는데 하나씩 알아가면서 내부적으로 어떤 방식으로 토큰을 발급 받고 사용하는지, 인증과 인가는 무엇이고 어떻게 다른지에 대해서 명확하게 이해하게 되었습니다.

이어서 다음 포스팅은 JWT에 대한 포스팅도 이어가보겠습니다.

질문과 피드백은 언제나 환영합니다 🤗


참고


OAuth 2.0 개념과 동작원리
OpenID(OIDC) 개념과 동작원리

profile
iOS 개발자

0개의 댓글