ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [OAuth] 소셜 로그인 구현: 1. OAuth 이해하기
    Today I Learned 2023. 7. 20. 16:37

    본 글에서는 Spring Boot, React를 사용하는 백엔드/프론트엔드 애플리케이션에서 소셜 로그인을 구현하기 위해 OAuth 2.0 인증 프레임워크에 대해 이해한 내용을 정리했다.

     

    소셜 로그인을 구현하는 전체 과정은 다음의 순서에 걸쳐서 작성될 예정이다.

    1. OAuth 이해하기
    2. 카카오 로그인 구현
    3. 네이버 로그인 구현

    OAuth 2.0

    OAuth는 특정 서버가 보유한 특정 사용자의 리소스에 대하여 타사 애플리케이션이 해당 리소스의 HTTP 서비스 액세스를 제한적으로 획득할 수 있도록 하는 인증 프레임워크이다.

     

    용어 정의

    OAuth에서 정의되는 주요 역할들은 다음과 같다.

    리소스 소유자 (Resource Owner)

    리소스 서버가 보유한 특정 리소스의 소유자이며, 해당 리소스에 대한 액세스 권한을 부여할 수 있는 개체를 의미한다. 리소스 사용자가 사람인 경우 최종 사용자(End-user)라고 지칭한다.
    ex. 네이버, 카카오에 개인정보를 제공한 사용자
    리소스 서버 (Resource Server)

    리소스 소유자의 리소스를 호스팅하는 서버로, 액세스 토큰을 사용하여 해당 리소스에 대한 접근 요청을 수락하고 응답한다.
    ex. 네이버, 카카오의 리소스 서버
    인가 서버 (Authorization Server)

    리소스 소유자의 인증을 받아 클라이언트에게 리소스에 대한 접근 권한을 부여하고, 액세스 토큰을 발급하는 서버이다. 인가 서버와 리소스 서버는 같은 서버일 수도, 별도의 서버일 수도 있다.
    ex. 네이버, 카카오의 인가 서버
    클라이언트 (Client)

    리소스 소유자로부터 특정 리소스에 대한 인증을 받은 뒤, 권한을 부여받은 상태로 리소스 서버에 해당 리소스를 요청하는 애플리케이션을 의미한다.
    ex. 사용자의 개인정보 리소스를 필요로 하는 어떤 다른 애플리케이션의 클라이언트 및 서버

     

    왜 OAuth를 사용하는가?

    특정 클라이언트가 어떤 사용자로부터 회원정보를 직접 입력받지 않고도 사용자의 정보를 획득할 수 있을까? 해당 사용자의 정보를 보유한 다른 리소스 서버가 존재한다면, 해당 리소스 서버로부터 정보를 제공받아 사용하는 방법을 취할 수 있다.

     

    해당 방법을 구현하기 위한 가장 간단한 방법으로는 리소스 소유자가 리소스 서버에 접근하기 위한 자격 증명 정보(계정명, 비밀번호 등)를 저장한 뒤, 필요 시 클라이언트가 직접 리소스 서버에 자격 증명 정보와 함께 요청을 보내 응답을 전달받는 방식을 생각해볼 수 있을 것이다.

     

    그러나 이 방식에는 몇 가지 결함이 존재한다.

    • 클라이언트가 대상 리소스 서버에 저장된 리소스 소유자의 리소스에 자유롭게 접근할 수 있게 된다. 이로 인해 리소스 소유자가 제공하기를 원하지 않는 데이터에도 클라이언트가 접근할 수 있는 가능성이 생긴다.

    • 가장 큰 문제는 클라이언트가 사용자의 자격 증명 정보를 평문이나 디코딩이 가능한 방식으로 저장하고 있어야 한다는 것이다. 만약 해당 클라이언트에서 모종의 이유로 정보들이 탈취당한다면, 해당 정보를 이용해 다른 리소스 서버에 존재하는 개인정보 또한 탈취당할 우려가 존재한다.

     

    OAuth는 리소스 획득 과정에서 권한 부여 계층을 도입하고 리소스 소유자의 역할을 도입해 위의 문제들을 해결한다.

     

     

    OAuth 프로토콜 플로우

    일반적인 OAuth 2.0을 활용한 리소스 정보를 획득하기 위한 흐름은 다음과 같다.

    (A-B) 권한 부여

    클라이언트가 리소스 소유자에게 리소스 서버의 특정 리소스에 접근하기 위한 권한 부여를 요청하면, 리소스 소유자가 인가 서버에 인증을 수행한 뒤 인가 서버가 클라이언트에 특정 리소스에 대한 접근 권한을 나타내는 '권한 부여(Authorization Grant)'를 제공한다.

     

    클라이언트가 권한 부여를 제공받는 방식들은 다음과 같다.

     

    1. 인증 코드 발급

    클라이언트는 리소스 소유자를 인가 서버로 안내한다. 인가 서버는 리소스 소유자를 인증하고, 성공적으로 인증된 경우 서버는 인증 코드를 Redirection URL에 포함하여 리소스 소유자를 클라이언트의 해당 URL에 리디렉션하는 방식으로 제공한다.

     

    인증 코드 발급 방식에서는 리소스 소유자 인증은 인가 서버에서만 수행되기 때문에, 리소스 소유자의 자격 증명 정보가 클라이언트에 공유되지 않아도 된다. 또한 인가 서버가 액세스 토큰을 발급하는 과정에서 해당 인증 코드를 이용해 클라이언트를 인증할 수 있으므로 액세스 토큰의 노출을 방지할 수 있다. 따라서 가장 일반적으로 사용되는 방식이다.

     

    2. 암시적 (Implicit) 권한 부여

    리소스 소유자가 인가 서버에 인증하면, 인가 서버가 클라이언트에 인증 코드가 아닌 액세스 토큰을 직접 반환한다. 인가 서버가 액세스 토큰을 발급하는 과정에서 클라이언트를 인증하지 않기 때문에, 액세스 토큰이 탈취되는 경우 잘못된 사용자나 클라이언트가 리소스 소유자의 정보에 접근할 수 있는 보안 취약점이 존재한다.

     

     

    이외의 권한 부여 방식은 해당 링크를 참조할 수 있다.

     

    (C-D) 액세스 토큰 발급

    클라이언트는 전달받은 권한 정보를 포함한 POST 요청을 인가 서버에 송신한다. 서버는 권한 정보의 유효성을 검사해 유효한 경우 액세스 토큰을 포함한 응답을 클라이언트에 반환한다. 액세스 토큰은 인코딩되어 있으며, 리소스 서버 및 인가 서버에 접근할 수 있는 리소스의 범위 및 기간 정보를 포함한다.

     

    (E-F) 리소스 획득

    클라이언트는 리소스 서버에 리소스 소유자로부터 권한을 부여받아 획득할 수 있는 리소스를 요청한다. 이때 액세스 토큰을 요청에 포함하여 인증한다. 리소스 서버는 액세스 토큰의 유효성을 검사하여 유효한 경우 해당 리소스를 클라이언트에 반환한다.

     

    References

    - The OAuth 2.0 Authorization Framework

      - 1.1. Roles

      - 1.2. Protocol Flow

      - 1.3. Authorization Code

      - 1.4. Access Token

      - 10.3. Security Considerations: Access Tokens

      - 10.16. Security Considerations: Misuse of Access Token to Impersonate Resource Owner in Implicit Flow

     

     

     

    댓글

Designed by Tistory.