포스트

[Web] OAuth

OAuth


OAuth인가를 위한 기술

  • OAuth(“Open Authorization”)는 인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로서 사용되는, 접근 위임을 위한 개방형 표준이다.
  • 이 매커니즘은 여러 기업들에 의해 사용되는데, 이를테면 아마존, 구글, 페이스북, 마이크로소프트, 트위터가 있으며 사용자들이 타사 애플리케이션이나 웹사이트의 계정에 관한 정보를 공유할 수 있게 허용한다.
  • OAuth는 사용자가 비밀번호를 제공하지 않고 다른 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있게 하는 개방형 표준기술이다.
  • 네이버, 카카오톡, Google, Facebook 등의 외부 계정을 기반으로 토큰을 이용하여 간편하게 회원가입 및 로그인할 수 있게 해주는 기술이다.

OAuth의 필요성


문제점

  • 기존 방식에서는 사용자의 구글 아이디와 패스워드를 받아 직접 로그인을 수행했다. 이러한 방식에는 몇 가지 중요한 문제가 있다.
    1. 신뢰 문제: 사용자가 캘린더를 신뢰하지 않을 수 있다. 사용자가 아이디와 패스워드를 제공했을 때, 캘린더 외 다른 서비스(예: 구글 포토, 드라이브)에 접근할 위험이 존재한다.
    2. 보안 부담: 캘린더가 사용자의 아이디와 패스워드를 관리해야 하는 부담이 있다. 이러한 정보를 제대로 관리하지 못해 노출될 경우, 심각한 보안 문제가 발생할 수 있다.
    3. 구글의 보안 무력화: 외부에서 아이디와 패스워드가 노출될 경우, 구글의 보안 조치가 무용지물이 될 수 있다.

해결책: OAuth

  • OAuth는 이러한 문제들을 해결하기 위해 탄생한 기술이다. OAuth의 기본 골자는 “인증은 유저가 직접 수행하고, 권한은 서비스가 받는 방식”이다.
    1. 신뢰 문제 해결: 사용자는 구글에 직접 아이디와 패스워드를 입력하여 인증을 수행한다.
    2. 보안 향상: 캘린더는 인증 과정에 포함되지 않으므로 중간에 탈취될 염려가 없다.
    3. 관리 부담 감소: 캘린더는 사용자의 아이디와 패스워드를 직접 관리할 필요가 없다.

OAuth 적용 후의 흐름


이미지

이미지

  1. 사용자 인증:
    • 사용자가 구글에 직접 아이디와 패스워드를 입력하여 인증을 수행한다.
    • 캘린더는 이 인증 과정에 포함되지 않는다.
  2. 권한 부여:
    • 인증이 유효하다고 확인되면, 구글은 캘린더에 사용자 캘린더에 접근할 수 있는 권한을 부여한다.
    • 캘린더는 이 권한으로 사용자 캘린더에 접근한다.
  3. 보안적인 이점:
    • 사용자는 권한 부여 과정에 관여하지 않는다.
    • 권한이 탈취될 수 있는 범위를 최소화하여 보안성을 높인다.

OAuth flow


이미지

  • OAuth 공식 문서에는 네 가지 흐름들이 정의되어 있다. 서비스의 대부분이 Authorization Code Flow를 지원하기 때문에 이 흐름만 알아도 OAuth 서비스를 이용하는 데 큰 불편함이 없을 것이다.
  • Authorization Code Flow는 특히 보안이 중요한 서버 사이드 애플리케이션에서 많이 사용되며, 클라이언트와 서버 간의 통신이 안전하게 이루어질 수 있도록 설계되었다. 이 방식에서는 사용자가 인증을 통해 발급받은 인증 코드를 클라이언트가 서버로 보내어 액세스 토큰을 교환하는 과정을 거친다. 이 과정에서 클라이언트 ID, 클라이언트 시크릿, 리다이렉션 URI 등의 정보를 사용하여 보안성을 강화한다.

OAuth Role


이미지

  • OAuth에서는 유저를 Resource Owner라고 부르고, 캘린더를 Client 또는 Third Party Application이라고 부른다. 구글의 경우 Authorization 서버와 Resource 서버로 나뉘어 역할을 수행한다.

이미지

  • 이를 조금 더 자세히 살펴보면 다음과 같다.
    • Resource Owner: 인증을 수행하는 주체이다.
    • Client: 권한을 위임받는 주체이다.
    • Authorization 서버: 인증을 검증하고 권한을 부여하는 역할을 한다.
    • Resource 서버: 인가를 수행하고 리소스를 제공하는 주체이다.

OAuth Setting


이미지

이미지

  • OAuth를 사용하기 위해 미리 해야 할 중요한 작업이 있다. 바로 OAuth를 제공해주는 서비스의 API에 자신의 서비스를 등록하는 것이다. 여기서 중요한 세 가지 요소는 다음과 같다.
    1. 클라이언트 ID: 서비스의 식별자로 사용된다.
    2. 클라이언트 보안 비밀번호: 권한을 요청하는 주체가 실제로 인증된 서비스인지 확인하는 수단이다.
    3. 리다이렉션 URI: 권한을 다시 서비스에게 전달하는 URI이다.
  • OAuth를 사용하려면 기본적으로 리다이렉션 URI를 제공해야 한다. 이를 제공하지 않는 브라우저에서는 OAuth를 사용할 수 없다.

이미지

  • OAuth 2.0에서는 권한을 제한을 둘 수 있다. 여기서는 수많은 권한들이 제공된다. 서비스에 필요한 권한들을 선택하여 추가하면 된다. OAuth를 실제로 적용하기 위한 설정들은 모두 마쳤다.

Authorizaiton Grant


이미지

이미지

  • Resource Owner가 OAuth 요청을 한다. 이는 “로그인 with 구글” 또는 “로그인 with 트위터” 버튼을 클릭하는 것과 같다.
  • 개발한 서비스는 로그인 페이지의 URL을 제공한다.
  • User-Agent(예: 크롬 웹 브라우저)에서 Authorization 서버로 URI를 요청하여 로그인 페이지에 접근한다.

이미지

  • 사용자는 로그인 페이지를 볼 수 있다. 사용자는 로그인 페이지에서 인증을 수행한다. 추가적으로 권한을 체크할 수 있으며, 이는 scope를 추가적으로 지정함으로써 이루어진다.
  • URI의 쿼리 파라미터로는 다음과 같은 정보들이 들어간다.
    • response_type: OAuth Flow의 Authorization 코드를 나타낸다.
    • client_id: 서비스의 식별자를 의미한다.
    • redirect_uri: 권한을 반환 받는 엔드포인트이다.
    • scope: 허용된 권한들이 포함된다.

이미지

  • 이 과정에서 클라이언트는 오직 로그인 페이지의 URL만을 제공하고, 실제로 로그인 페이지나 인증 과정에 대한 수행은 Resource Owner와 Authorization 서버만이 참여한다. 이것이 OAuth의 가장 기본적인 골자인 인증과 인가의 대상을 분리하는 것이다.
  • User-Agent라는 요소는 Resource Owner가 인증을 수행하기 위한 매개체로, 간단하게는 크롬 웹 브라우저라고 생각하면 된다.

이미지

  • 인증이 유효한 경우, authorization 서버는 access token 또는 권한을 받을 수 있는 authorization 코드를 반환하다. 클라이언트는 이 authorization 코드를 이용하여 access token을 요청한다.

이미지

  • 이때 요청에는 다음과 같은 옵션이 들어간다.
    • code: 앞서 반환받은 authorization 코드
    • client_id: 클라이언트의 식별자
    • client_secret: OAuth 세팅에서 등록한 클라이언트인지 확인하는 용도로 사용된다.
    • redirect_uri: authorization 코드나 access token을 반환받을 엔드포인트를 의미한다.
    • grant_type: authorization code가 들어가며, 네 가지 흐름 중 하나를 지정한다.

이미지

  • 인증이 완료되면 authorization 서버는 access token과 refresh token을 반환한다. 이 과정에서도 주의해야 할 점은 클라이언트와 authorization 서버만이 참여한다는 것이다. 권한부여 범위를 제한하여 권한이 탈취될 위험을 줄이게 된다.
  • 또한, 이러한 통신은 HTTPS로 암호화되어야 한다. 이는 공식 문서에서 정해진 사항은 아니지만, 권장되는 사항이며 대부분의 서비스에서도 HTTPS가 구현되어 있지 않다면 인증 과정에서 오류가 발생할 수 있다. 따라서 OAuth를 사용한다면 먼저 HTTPS를 구축하는 것이 좋다.
  • 토큰 종류로는 Access Token과 Refresh Token이 있다. Access Token은 만료 시간이 있으며 만료되면 다시 요청해야 한다. Refresh Token은 만료되면 처음부터 인증 과정을 다시 진행해야 한다.

Using Resource


이미지

  • 권한을 모두 부여 받으면 Resource Owner가 서비스를 요청할 때, Client는 이 access token을 함께 리소스를 요청한다. Resource 서버는 이 access token을 검증한 후에 요청된 리소스를 반환해 준다. 클라이언트는 이를 가공하여 최종적으로 서비스를 제공하게 된다.

소셜로그인 - OAuth 2.0


이미지

  • 소셜 로그인은 OAuth와 조금 다른 주제이지만, 백엔드(Spring 등)에서의 코드를 통해 간단하게 살펴보면, 먼저, 파라미터로 Authorization 코드를 받은 후, 이를 사용하여 소셜 로그인을 수행한다.
  • 예를 들어, GitHub의 경우, 해당 코드를 이용하여 GitHub에서 access token을 발급받는다. 이것이 우리가 이전에 살펴본 OAuth 플로우이다.
  • 그 다음, GitHub에서 받은 access token을 사용하여 유저를 식별할 수 있는 정보인 GitHub 프로파일을 요청한다. 이 프로파일을 기반으로 멤버를 생성하거나 조회할 수 있다.
  • 이렇게 받은 멤버 정보를 기반으로 JWT 토큰을 생성하여 클라이언트에게 반환한다. 이로써 OAuth를 통해 인증된 유저에 대한 정보를 얻을 수 있다.

  • 소셜 로그인을 하더라도 실제로 사용자의 정보를 관리하기 위해서는 별도의 멤버 DB를 구축해야 한다. OAuth가 담당하는 것은 사용자의 아이디와 패스워드와 같은 정보를 다른 OAuth 제공자에게 위임하는 것이다. 우리 서비스에서는 사용자의 찜 정보나 일정과 같은 추가적인 정보를 관리하기 위해 별도의 멤버 DB를 구축해야 한다.

소셜로그인 - Open ID Connect


이미지

이미지

  • 소셜 로그인은 인증, OAuth는 인가를 위한 기술이다. 인증을 지원하기 위해 OAuth 2.0에서는 OpenID Connect라는 기술이 추가되었다.
  • 기존의 OAuth와 비슷하지만 ID token이라는 것이 추가된다. 이 ID token은 권한을 부여받는 과정에서 함께 발급된다. 이 ID token은 인증을 위한 것이므로, 저희가 받는 것은 access token이 아니라 ID token이다.
  • 이 ID token은 주로 JWT 형식으로 되어있다. 토큰의 가운데 페이로드 부분을 디코딩하면 유저의 식별자를 얻을 수 있고, 이를 통해 멤버를 생성하거나 회원가입을 할 수 있다. 또, JWT를 만들어서 반환해줄 수 있다.
  • 앞서 보여준 코드는 OAuth로 소셜 로그인을 구현하는 하나의 방법에 불과하며, 절대적인 방법은 아니다.

소셜로그인 - 무엇을 골라야 할까?


기업OAuthOIDC
구글oo
깃허브ox
네이버ox
카카오oo(optional)
페이스북oo
  • OAuth를 이용한 소셜 로그인 구현으은 주어진 제공자의 기술을 따라야 한다. 구글을 사용하고 싶다면 구글의 OAuth를 사용하고, 네이버 등이 OpenID Connect를 제공하지 않는다면 일반적인 OAuth를 통해 구현할 수 있다.

요약


  • 권한을 받기 위해서는 먼저 인증이 선행되어야 한다. 인증은 유저가 직접, 권한은 서비스에게
  • OAuth는 인가 과정에서 인증을 따로 분리하기 위한 기술이고, 인증은 유저가 직접 권한을 서비스에게 부여하는 방식으로 동작한다.
  • OAuth는 인증과 권한 부여 과정을 분리하여 보안성을 높이고, 관리 부담을 줄이기 위해 탄생한 기술이다.

사용 용어


  • 사용자: 계정을 가지고 있는 개인
  • 소비자: OAuth를 사용해 서비스 제공자에게 접근하는 웹사이트나 애플리케이션
  • 서비스 제공자: OAuth를 통해 접근을 지원하는 웹 애플리케이션
  • 소비자 비밀번호: 서비스 제공자에서 소비자가 자신임을 인증하기 위한 키
  • 요청 토큰: 소비자가 사용자에게 접근 권한을 인증받기 위해 필요한 정보가 담긴 토큰
  • 접근 토큰: 인증 후에 사용자가 서비스 제공자가 아닌 소비자를 통해 보호된 자원에 접근하기 위한 키 값

인증 과정


인증은 유저가 직접, 권한은 서비스에게

  1. 소비자 → 서비스 제공자: 소비자가 서비스 제공자에게 요청 토큰을 요청한다.
  2. 서비스 제공자 → 소비자: 서비스 제공자가 소비자에게 요청 토큰을 발급해준다.
  3. 소비자 → 사용자: 소비자가 사용자를 서비스 제공자로 이동시킨다. 이때 사용자 인증이 수행된다.
  4. 서비스 제공자 → 사용자: 서비스 제공자가 사용자를 소비자로 다시 이동시킨다.
  5. 소비자 → 서비스 제공자: 소비자가 서비스 제공자에게 접근 토큰을 요청한다.
  6. 서비스 제공자 → 소비자: 서비스 제공자가 접근 토큰을 발급한다.
  7. 소비자 → 보호 자원: 소비자가 발급된 접근 토큰을 이용해서 사용자 정보에 접근한다.

이 과정을 통해 소비자는 OAuth를 이용하여 사용자 인증을 받아 서비스 제공자의 보호된 자원에 접근할 수 있게 된다.


참고 자료


이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.