상세 컨텐츠

본문 제목

Spring Security와 OAuth2를 이용한 소셜 로그인

기술정리

by 승학이 2024. 2. 2. 21:38

본문

1. Spring Security란?

Spring 기반의 어플리케이션의 인증과 권한 부여을 담당하는 스프링 프레임워크 하위 프레임워크입니다.

Spring Security는 "인증체크", "권한부여"에 대한 부분을 Filter 의 흐름으로 처리합니다.

 

2. Spring Security OAuth2 동작 방식

 

OAuth 프로토콜의 동작 방식

 

OAuth2는 인터넷에서 사용자 인증과 권한 부여를 위한 표준 프로토콜입니다. 이 프로토콜은 사용자가 한 서비스(예: 나의 웹 애플리케이션)에 로그인할 때, 다른 서비스(예: 페이스북, 구글, 카카오 등)의 인증 정보를 사용할 수 있게 해줍니다. 이 과정은 다음과 같이 진행됩니다:

  1. 사용자가 서비스에 접근하려고 시도합니다. 사용자가 나의 웹 사이트에 로그인하려고 할 때, 일반적으로 이메일과 비밀번호를 입력하는 대신, "카카오로 로그인하기", "구글로 로그인하기"와 같은 옵션을 선택할 수 있습니다.
  2. 서비스(클라이언트)는 인증 서버에 로그인 페이지를 요청합니다. 사용자가 "카카오로 로그인하기"를 선택하면, 나의 서비스는 카카오의 인증 서버에 사용자의 클라이언트 ID와 함께 로그인 페이지를 요청합니다. 클라이언트 ID는 고객의 서비스가 카카오에 등록될 때 부여받은 고유 식별자입니다.
  3. 사용자가 로그인 페이지에서 아이디와 비밀번호를 입력합니다. 이 페이지는 카카오의 것이므로, 사용자는 카카오에 직접 로그인합니다. 이 과정은 사용자의 로그인 정보가 나의 서비스에 노출되지 않게 합니다.
  4. 인증 서버는 Authorization Code를 발급합니다. 로그인이 성공하면, 카카오는 사용자의 브라우저를 나의 서비스로 리디렉션하며, 이 때 Authorization Code도 함께 전달됩니다. 이 코드는 Access Token을 얻기 위한 일종의 중간 단계입니다. 
  5. 내 서비스는 Authorization Code를 사용해 Access Token을 요청합니다. 나의 서버는 카카오에 이 코드와 함께 Access Token을 요청합니다. 이때, 클라이언트 ID와 클라이언트 비밀번호도 함께 제공되어야 합니다.
  6. Access Token을 받습니다. 카카오는 요청이 유효하다고 판단되면 Access Token을 나의의 서비스에 발급합니다. 이 토큰은 카카오에 저장된 사용자의 정보에 접근할 수 있는 '열쇠'와 같습니다.
  7. 내 서비스는 Access Token을 사용해 사용자 정보를 요청합니다. 마지막으로, 나의 서비스는 이 토큰을 사용하여 카카오로부터 사용자의 프로필 정보(예: 이름, 이메일 등)를 요청합니다. 카카오는 요청을 승인하고 필요한 정보를 나의 서비스에 제공합니다.

이렇게 OAuth2는 사용자가 다른 서비스의 인증 정보를 사용하여 나의 서비스에 안전하게 로그인할 수 있도록 해줍니다. 이 과정은 사용자에게는 편리하고, 서비스 제공자에게는 사용자의 인증 정보를 직접 관리할 필요가 없어 보안적으로도 유리합니다.

 

리다렉션이란?

리디렉션(redirect)이란 웹 브라우저가 어떤 웹 페이지나 리소스를 요청했을 때, 그 요청을 다른 페이지나 리소스로 넘겨주는 것을 말합니다. OAuth2 인증 과정에서의 리디렉션은 사용자가 외부 서비스(예: 카카오)를 통해 로그인한 후, 사용자의 웹 브라우저를 다시 원래의 서비스(예: 나의 웹 사이트)로 돌려보내는 과정을 말합니다. 이 과정은 아래와 같이 진행됩니다:

  1. 로그인 페이지 요청: 사용자가 나의 서비스에서 "카카오로 로그인하기"를 클릭합니다.
  2. 카카오 인증 페이지로 이동: 나의 서비스는 사용자를 카카오의 인증 페이지로 리디렉션합니다. 여기서 사용자는 카카오 계정으로 로그인합니다.
  3. Authorization Code 발급: 로그인이 성공하면, 카카오는 사용자에게 Authorization Code를 발급합니다. 이 코드는 특정한 요청을 인증하는데 사용됩니다.
  4. 나의 서비스로 리디렉션: 카카오는 이제 사용자의 웹 브라우저를 나의 서비스로 다시 리디렉션합니다. 이 때, URL에 Authorization Code가 포함되어 있습니다.

이 리디렉션 과정에서 중요한 것은 사용자의 브라우저가 자동으로 나의 서비스로 돌아온다는 점입니다. 리디렉션 URL은 일반적으로 OAuth2 설정 과정에서 나의 서비스에 등록해둔 "리디렉션 URI"로 설정됩니다. 이 URI는 인증 과정이 끝난 후 사용자가 돌아갈 웹 페이지의 주소입니다.

예를 들어, 나의 웹 애플리케이션이 https://example.com/oauth2/callback을 리디렉션 URI로 사용한다고 가정해 봅시다. 그렇다면 카카오는 사용자를 로그인 후 https://example.com/oauth2/callback?code=AUTHORIZATION_CODE와 같은 형식의 URL로 리디렉션합니다. 여기서 AUTHORIZATION_CODE는 카카오로부터 발급받은 실제 인증 코드를 나타냅니다.

이 URL에 접근함으로써 나의 서비스는 URL에 포함된 Authorization Code를 사용하여 카카오에게 Access Token을 요청할 수 있게 됩니다. 이렇게 리디렉션을 통해 사용자는 자연스럽게 나의 서비스로 돌아오며, 나의 서비스는 이어지는 인증 과정을 계속 진행할 수 있습니다.

 

OAuth2 client library를 이용한 Social Login

OAuth2 client library란?

  • OAuth 프로토콜을 사용하는(카카오톡, 구글, 네이버, 페이스북 등) 방식를 편리하게 사용할수 있게 기능을 제공해주는 라이브러리
  • OAuth2 Client library가 Spring Security OAuth2 프로토콜을 이용할때 Provider(들)을 기본적으로 제공해어서 편리하게 도와준다.(google, facebook, github등) 하지만 kakao, naver 를 사용할때에는 별도의 provider를 생성해주어야 된다.
  • OAuth2 client library가 제공되는 서비스 플랫폼에 한해서 약속된 규칙에 의거하여 코드를 받는uri, 토큰 받는 uri, 사용자 정보요청 uri등을 만들어 받아와준다.

3.1 build.gradle 설정

1. 기본적으로 Spring Security 와 OAuth2-client 라이브러리를 추가한다. -> build.gradle

3.2 application.yml 설정

 

1. Client-id, Client-secret을 카카오 developers 어플리케이션에서 발급받은 코드를 넣는다. 

2. scope에는 카카오 플랫폼의 사용자 동의체크에서 사용자 정보중 필요한 정보의 필드를 넣는다. 

3. authorization-grant-type
-> 권한 부여 방식의 종류로서 code, token을 사용하는 방식

4. redirect-uri
->각 플랫폼에서 입력한 code를 받는 uri

5. 필요한 플랫폼 provider 정의
-> OAuth2-client 라이브러리가 제공하지 않는 provider는 위와 같이 필요한 정보들을 입력해준다.

 

3.3 Domain User 생성

 

3.4 User Repository 생성

 

3.5 Security Config

OAuth2 프로토콜 방식을 사용하지 않는 방식(formLogin(), 일반 로그인) 에서는 Spring Security가 "/loginForm" uri로 이동시킴

Spring Security Filter가 자동으로 "/login" post방식으로 오는 uri를 낚아채어 UserDetalisService타입의 객체의 loadUserByUsername 메소드를 호출해둔다.

OAuth2 프로톨을 방식을 사용할때에는(oauth2Login()) DefalutOAuth2UserService(여기선 PrincipalOauthUserService가 해당 타입을 상속함) 타입의 loadUser 메소드를 호출한다.

 

3.6 PrincipalDetails (UserDtalis, OAuth2User를 구현한 객체)

앞서 스프링 시큐리티 세션 영역에는 Authentication객체가 들어가게 되고 Authentication객체안에는
UserDetails, OAuth2User객체가 들어갈 수 있다.

 

컨트롤러에서 필요한 Authentication객체를 가져올때 일반 로그인이든 OAuth2 로그인이든 상관없이 동일한 객체를 가져올수 있게 하기 위해서 함께 상속받았다.

 

3.7 PrincipalService (UserDetailService를 상속함)

 

PrincipalDetails(UserDetails 상속)객체를 반환해주므로 Authentication 타입객체로 만들어질수 있고 스프링 시큐리티 세션안에 들어갈수 있게 된다.

 

3.8 PricipalOauthUserSevice (DefaultOAuth2UserService을 상속)

OAuth2-client 라이브러리가 code단계 처리후 OAuth2UserRequest객체에 엑세스 토큰, 플랫폼 사용자 고유 key값을 반환해준다.

OAuth2UserRequest객체의 상위타입인 OAuth2User객체에 요청한 사용자 정보를 반환해준다.

요청한 사용자 정보에 대한 Response의 형식이 다르다.

OAuth2-client가 지원해주는 provider(구글, 페이스북등)는 Map형태로 key,Object로 반환해준다.

OAuth2-client가 지원해주지 않은 provider(네이버, 카카오톡)는 json형태로 반환해준다.

 

PrincipalDetails(OAuth2User 상속)객체를 반환해주므로 Authentication 타입객체로 만들어질수 있고 스프링 시큐리티 세션안에 들어갈수 있게 된다.

 

참고 링크 : https://velog.io/@rnqhstlr2297/Spring-Security-OAuth2-%EC%86%8C%EC%85%9C%EB%A1%9C%EA%B7%B8%EC%9D%B8

 

 

'기술정리' 카테고리의 다른 글

냉집사 Query Dsl 정리  (1) 2024.02.09
NGINX  (0) 2024.02.09
데이터 접근 기술 - 테스트  (2) 2024.02.05
MyBatis  (0) 2024.02.02
Jdbc Template  (0) 2024.02.02

관련글 더보기