Team

[CS스터디] OAuth 2.0

seungh2 2023. 4. 30. 19:09

OAuth 2.0

  • 인증 및 인가 프로토콜
  • third-party application 에 대한 access 권한을 부여할 수 있다.
  • 리소스 소유자를 대신해 리소스 서버에서 제공하는 자원에 대한 접근 권한을 위임하는 방식으로 작동된다.
  • 구글, 페이스북, 네이버, 카카오 등 외부 소셜 계정을 기반으로 간편하게 인증할 수 있도록 해준다.

 

OAuth 2.0 구성요소

  1. Client (클라이언트)
    1. OAuth 2.0 서비스에 액세스하는 애플리케이션 또는 서비스
    2. Resource Owner가 소유한 리소스에 대한 접근 권한을 얻기 위해 인증 및 인가를 요청한다.
    3. 직접 개발한 서비스
  2. Resource Owner (리소스 소유자)
    1. OAuth 2.0 서비스에 있는 사용자. 보호된 리소스에 대한 접근 권한을 부여할 수 있는 entity
    2. 유저 (소셜 로그인을 사용할 사용자)
  3. Authorization Server (인가 서버)
    1. OAuth 2.0 서비스에 인가하는 서버, 권한을 부여해주는 서버
    2. Authorization Code를 발급해준다.
  4. Resource Server (리소스 서버)
    1. OAuth 2.0 서비스에서 제공하는 데이터 및 기능을 포함하는 서버
    2. Access Token을 사용해 보호된 리소스에 대한 요청을 수락하고 응답을 가능하게 하는 보호된 리소스를 호스팅하는 서버
    3. 구글, 페이스북, 네이버, 카카오

OAuth 2.0 Authorization Grant 방식

Access Token을 얻기 위해 Client가 사용하는 Resource Owner의 권한을 나타내는 credential(자격 증명)

  • Authorization Code Grant
    • Client는 Resource Owner에게 직접 권한 부여을 요청하는 대신에 Authorization Server로 이동시킨다.
    • Authorization Server가 Resource Owner의 동의를 받고 Authorization Code를 발급해준다.
    • 발급한 Authorization Code와 함께 Resource Owner를 Client로 이동시킨다.
    • 이 Authorization Code로 Authorization Server에게 Access Token을 발급받을 수 있다.
      바로 Client에게 직접 전송하기 때문에 Resource Owner나 다른 사람에게 노출되지 않는 보안 이점이 있다.
  • Implicit Grant
    • Authorization Code와 같이 중간 Credential 없이 바로 Access Token을 Client에게 전달한다.
    • Access Token을 발급할 때, Client를 인증하지 않고 바로 발급하기 때문에 노출 위험이 있다. (이를 방지하기 위해 Access Token의 만료기한을 짧게 한다.)
    • Access Token을 발급받는데 필요한 왕복 횟수를 줄이기 때문에 일부 경우에 응답성과 효율성을 향상시킨다.
    • 권장 X
  • Resource Owner Password Credentials Grant
    • 사용자 이름과 비밀번호를 사용하여 Access Token을 얻는다.
    • 권장 X
  • Client Credentials Grant
    • 클라이언트 자격 증명을 사용하여 Access Token을 얻는다.

OAuth 2.0 흐름

(A) Client가 Resource Owner에게 권한 부여를 요청한다.

(B) Client는 Resource Owner의 권한을 나타내는 자격 증명인 Authorization Grant를 수신한다.

(C) Client가 (B)에서 받은 Authorization Grant로 Access Token을 요청한다.

(D) Authorization Server Authorization Grant의 유효성을 검사한다. Authorization Grant가 유효한 경우 Access Token을 발급한다.

(E) Client는 Access Token을 사용하여 Resource Server에 보호된 리소스를 요청한다.

(F) Resource ServerAccess Token을 검증하고 유효한 경우 요청을 처리한다.


Access Token

  • 보호된 자원에 접근하기 위해 사용되는 Credential
  • Client에 발급된 권한을 나타내는 문자열

Refresh Token

  • Access Token을 발급받기 위해 사용되는 Credential
  • Access Token이 만료되었으면 Refresh Token을 이용해 새 Access Token을 얻을 수 있다.

(A) Client는 Authorization Grant를 보내며 Access Token을 요청한다.

(B) Authorization ServerAuthorization Grant를 확인하고, 유효한 경우 Access Token과 Refresh Token을 발급한다.

(C) Client는 Access Token으로 Resource Server에 보호된 리소스를 요청한다.

(D) Resource Server는 Access Token을 검증하고 유효한 경우 요청을 처리한다.

(E) Access Token이 만료될 때까지 (C) 및 (D) 단계를 반복한다.


(F) Access Token이 잘못되었으면(ex. Access Token 만료) Resource Server가 잘못된 토큰 오류를 반환한다.

(G) Client는 Refresh Token으로 새 Access Token을 요청한다.

(H) Authorization Server는 Refresh Token을 확인하고, 유효한 경우 새 Access Token(및 선택적으로 새 Refresh Token)을 발급한다.

 

카카오 로그인

준비

  • 카카오에서 내 Application 만들기
  • 카카오 로그인 활성화 설정에서 활성화 상태를 ON으로 설정하기
  • 카카오 로그인 활성화 설정에서 Redirect URI 설정하기 (Redirect URI를 통해 Authorization Code를 받을 수 있다.)

  • 카카오 로그인 동의항목 설정하기

  • appllication.yml 파일 설정하기
spring:
  datasource:
    url: [입력] ex) jdbc:mysql://localhost:3306/DB이름
    driver-class-name: [입력] ex) com.mysql.cj.jdbc.Driver
    username: [입력]
    password: [입력]

  security:
    oauth2:
      client:
        registration:
          kakao:
            client-id: [REST API 키]
            redirect-uri: [Redirect URI, 내 어플리케이션에서 설정한 Redirect URI]
            authorization-grant-type: authorization_code
            client-authentication-method: POST
            client-name: Kakao
            scope: # 설정한 동의항목 명시
              - profile_nickname
              - account_email
        provider:	# 카카오나 네이버는 provider를 직접 설정해줘야 한다.
          kakao:
            authorization-uri: https://kauth.kakao.com/oauth/authorize
            token-uri: https://kauth.kakao.com/oauth/token
            user-info-uri: https://kapi.kakao.com/v2/user/me
            user-name-attribute: id

카카오에서 사용자 정보 가져오는 방법

    private static OAuthAttributes ofKakao(String userNameAttributeName, Map<String, Object> attributes) {
        // kakao_account에 유저정보가 있다. (email)
        Map<String, Object> kakaoAccount = (Map<String, Object>)attributes.get("kakao_account");
        // kakao_account안에 profile이라는 JSON객체 안에 scope에서 설정한 정보가 있다. (nickname)
        Map<String, Object> kakaoProfile = (Map<String, Object>)kakaoAccount.get("profile");

        return OAuthAttributes.builder()
                .name((String) kakaoProfile.get("nickname"))
                .email((String) kakaoAccount.get("email"))
                .attributes(attributes)
                .nameAttributeKey(userNameAttributeName)
                .build();
    }

 

과정

사용자 클라이언트 = Resource Owner

서비스 서버 = Client

카카오 인증 서버 = Authorization Server

카카오 API 서버 = Resource Server


Step 3 : 서비스 로그인에서 "서비스 세션 발급"에서 JWT 사용

서버 기반 인증 방식

  • 서버측에서 사용자 정보를 저장하는 것.
  • 보통 Spring Security에서는 session을 이용해 처리하는데, MSA를 하거나 서버가 확장되면 모든 서버에게 세션의 정보를 공유해야 한다.
  • Access Token은 사용자 정보에 직접 접근할 수 있도록 해주는 정보를 담고 있고 Refresh Token에 비해 짧은 만료기간을 가지고 주로 세션에 담아 관리한다.
  • Refresh Token은 새로운 Access Token을 발급하기 위한 정보를 담고 있다. 이를 통해 Auth Server에 요청해 새로운 Access Token을 발급받을 수 있다. 외부에 노출되지 않도록 DB에 저장한다.
  • 요청마다 Access Token의 유효성을 검증해야 하고 업데이트를 해줘야 한다.
  • 서버의 수가 많은 경우, Access Token의 유효성 및 권한 확인을 위한 요청이 Auth Server에 많이 발생하기 때문에 서버의 부하로 이어질 수 있다.

JWT 기반 인증 방식

  • JWT는 Claim 기반 방식을 사용하기 때문에 사용자에 대한 의미 있는 정보로 이루어져있다.
  • Auth Server에 검증 요청을 보내는 과정을 생략하고 각 서버에서 수행할 수 있다.
  • 서버의 수에 상관없이 토큰을 인증하는 방식을 알고 있으면 인증 할 수 있다.
  • 헤더에 JWT 값을 넣어 보내야 하기 때문에 데이터가 증가해 네트워크 부하가 일어날 수 있다.

 


https://docs.spring.io/spring-security/reference/servlet/oauth2/index.html

 

OAuth2 :: Spring Security

Spring Security provides comprehensive OAuth 2 support. This section discusses how to integrate OAuth 2 into your servlet based application.

docs.spring.io

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

 

RFC ft-ietf-oauth-v2: 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://deeplify.dev/back-end/spring/oauth2-social-login

 

[Spring Boot] OAuth2 소셜 로그인 가이드 (구글, 페이스북, 네이버, 카카오)

스프링부트를 이용하여 구글, 페이스북, 네이버, 카카오 OAuth2 로그인 구현하는 방법에 대해서 소개합니다.

deeplify.dev

 

728x90