Group Study (2022-2023)/Spring 입문

4주차 레퍼런스

민휘 2023. 1. 12. 18:34

4주차 레퍼런스 문서와 멤버분들이 추가 공부한 내용을 스크랩했습니다.

4주차 레퍼런스 제공

OAuth2.0

OAuth2 소개

OAuth2는 일종의 인증 프로토콜입니다. 소셜 인증을 통한 로그인 및 권한 제어를 위해 사용됩니다. 그래서 구글, 트위터, 깃허브, 페이스북, 네이버 등 대부분 소셜 인증 기능을 가진 provider는 표준 인증 방식으로 OAuth2를 채택하여 인증 관련 API를 제공합니다.

OAuth2의 구성 요소

OAuth2의 구현체를 활용하면, 유저들의 정보를 대량으로 가지고 있는 소셜 회사(구글, 네이버 등)로부터 유저의 데이터를 애플리케이션 서버에 가져와 활용할 수 있습니다. 유저가 서비스를 사용하면서 소셜 로그인을 원할 경우, 해당 요청은 브라우저, 즉 클라이언트로부터 받아옵니다. OAuth2의 핵심 구성 요소를 뽑아보자면 소셜 로그인을 요청하는 유저(리소스 주인), 유저의 요청을 받아 애플리케이션 서버에 로그인 요청을 날리는 클라이언트, 데이터를 제공하는 리소스 서버, 데이터를 받아와 활용하는 애플리케이션 서버, 애플리케이션 서버가 리소스 서버로부터 데이터를 받아오기 위한 인증을 처리하는 권한 서버로 정리할 수 있습니다.

OAuth2 플로우

그림에는 나와있지 않지만, 1번 이전에 유저가 애플리케이션에게 로그인을 요청합니다. 유저로부터 로그인 요청을 받은 애플리케이션이 유저에게 내가 너의 어떤 정보에 접근해도 되겠니? (이메일, 이름, 프로필 사진 등) 승인을 요청합니다. 유저가 해당 요청을 승인하면 리소스를 받아올 준비를 합니다.

그런데, 그림을 보면 리소스 서버로부터 데이터를 받아오기 전, 두 가지 정보를 주고 받는 것을 볼 수 있습니다. Authorization Grant와 Access Token인데요. 어떠한 목적으로 사용되길래 정보가 두개 필요한걸까요?

Authorization Grant, 그중 표준이 되는 방식인 Authorization Code는 권한 서버로부터 인증을 받고 권한을 허가 받습니다. 이 코드를 받은 클라이언트는 코드를 권한 서버에 전송하여 Access Token을 받습니다. 받은 토큰으로 리소스 서버에 유저 데이터를 요청하여 받아옵니다. 정리하자면 Authorization Code는 권한 서버로부터 인증을 받기 위함이고, Access Token은 리소스 서버로부터 데이터를 가져오기 위해 사용되는 키입니다. 이 방법은 access token을 바로 Client(클라이언트)로 곧바로 전달하지 않기 때문에 전달과정에서 생길 수 있는 유출 위험을 줄일 수 있습니다.

제가 위의 단락에서 Code가 Grant 중 하나이다라는 표현을 캐치하셨나요? OAuth2 프로토콜은 다양한 클라이언트 환경에 적용할 수 있도록, 권한 부여 방식에 따른 프로토콜을 4가지 종류로 분류했습니다. 저희가 알아본 인증 코드를 사용하는 방식이 가장 기본이 됩니다. 그외에도 Implicit Grant, Resource Owner Password Credentials Grant, Client Credentials Grant 방식 등이 있습니다.

OAuth2는 소셜 로그인을 구현하려면 필수적으로 알아야하는 프로토콜이라, 관련 강의나 자료가 많습니다. 개인적으로 추천하는 자료 위주로 링크에 남길테니, 제 설명만으로 이해가 충분히 되지 않으신 분들은 참고해주세요!

WEB2 - OAuth 2.0 - 생활코딩

 

WEB2 - OAuth 2.0 - 생활코딩

수업소개 사용자가 가입된 서비스의 API에 접근하기 위해서는 사용자로부터 권한을 위임 받아야 합니다. 이 때 사용자의 패스워드 없이도 권한을 위임 받을 수 있는 방법이 필요합니다. 이를 위

opentutorials.org

내 맘대로 OAuth 2.0 정리! - 이상한모임

 

내 맘대로 OAuth 2.0 정리! - 이상한모임

우리 회사에서 왜 OAuth 2.0 기반의 인증 및 권한부여 방식으로 Resource Owner Password Credentials를 선택했는지에 대한 장황한 변명을 들어보자!

blog.weirdx.io

MDS인텔리전스 블로그 : 네이버 블로그

 

OAuth 2.0 동작 방식의 이해

OAuth 2.0(Open Authorization 2.0, OAuth2)은 인증을 위한 개방형 표준 프로토콜입니다. 이 프로토...

blog.naver.com

구글 로그인과 실습 코드 비교

교재 실습을 하면서 다양한 uri들이 나왔는데요. 해당 요청들이 구글 로그인의 어느 부분과 대응되는지 살펴보겠습니다.

구글 로그인 플로우

구글 로그인 플로우입니다. 저희가 앞에서 살펴본 OAuth2의 플로우와 다른 부분이 없습니다. 이 그림에서는 클라이언트와 서버를 App으로, 권한 서버와 리소스 서버를 한번에 Google Servers로 퉁쳐서 표현하고 있네요. 실제 구현을 할 때도 uri로 요청을 표현하기 때문에, 어느 서버에 요청을 날려야하는지 코드로 지정해줄 필요가 없습니다.

리디렉션 uri

교재의 172p에 보면 구글 서비스를 등록할 때 리디렉션 uri(**http://localhost:8080/login/oauth2/code/google**)를 입력하는 것을 볼 수 있습니다. 리디렉션 uri는 무엇일까요? 구글 로그인 플로우를 더 자세하게 볼 필요가 있습니다.

4번 과정을 통해 브라우저는 권한을 받아 인증 코드를 받아옵니다. 브라우저가 서버 애플리케이션에 코드를 함께 보내 인증 토큰을 받아오라는 요청을 날리는데요, 이때 브라우저가 서버 애플리케이션에 자동으로 요청을 보낼 uri를 리디렉션 uri라고 합니다. OAuth2.0의 플로우 그림과 다른 점은 코드를 받아 토큰을 요청하는 책임이 애플리케이션 서버로 바뀌었다는 점이네요.

로그인 버튼에 링크된 uri

<a href="**/oauth2/authorization/google**" class="btn btn-success active" role="button">Google Login</a>
<a href="**/oauth2/authorization/naver**" class="btn btn-secondary active" role="button">Naver Login</a>

로그인 버튼을 클릭하면 브라우저는 애플리케이션 서버에 해당 요청을 날립니다. 저희는 해당 요청을 처리할 컨트롤러를 만들지 않았는데요, 스프링 시큐리티에서 기본적으로 제공하는 로그인 URL이므로 저희는 코드를 작성할 필요가 없었습니다. 구글, 네이버 서버에 인증 코드를 받아오는 과정을 처리합니다.

로그인 성공, 로그아웃 성공시 uri

.and()
.logout()
.logoutSuccessUrl("/")

.and()
.oauth2Login()
.userInfoEndpoint()
.userService(customOAuth2UserService)

SecurityConfig 파일에서 로그인에 성공한 경우, 로그아웃에 성공한 경우 리다이렉트할 uri를 지정했습니다. 로그아웃은 인덱스 페이지로 이동하는 것이 직관적으로 보이는데, 로그인이 성공한 경우는 어떻게 인덱스 페이지로 이동하는 것일까요? 로그인이 성공한 경우에는 원래 로그인을 시도했던 페이지로 로딩합니다. 이때 customOAuth2UserService에서 세션 객체에 현재 로그인한 유저의 정보를 담아놓았기 때문에 인덱스 페이지에 로딩되었을 때 유저 정보를 화면에 출력할 수 있었던 것입니다.

그외의 Service, Dto, Controller

교재 실습을 하면서 Spring Security가 제공하는 인터페이스와 구현체를 상속받아 저희 애플리케이션 서버의 요구 사항에 맞는 기능을 구현했습니다. 저희가 작성한 코드를 보면서, 리소스 서버로부터 데이터를 가져온 이후 어떻게 유저 정보를 활용하는 동작을 정의하고 있는지 되짚어보시길 바랄게요. 시간은 오래 걸리겠지만, 그만큼 기억에 더 오래 남을 것입니다! (오랜만에 쓰니 말투가 번역체 같네요..🤪)

Spring Security

이번 장에서 Spring Security를 사용해 소셜 로그인을 구현해봤습니다. 사실 Spring Security는 OAuth보다 훨씬 넓은 범주의 애플리케이션 보안을 맡고 있는 프레임워크입니다. Spring Security는 Spring 기반의 애플리케이션 보안(인증, 권한, 인가)을 담당하는 스프링 하위 프레임워크입니다. Spring Security는 인증과 권한에 대한 부분을 Filter 흐름에 따라 처리하고 있습니다.

헛.. 두 문장 안에 모르는 개념들이 마구 나오고 있네요. Spring Security를 이해할 때 다음과 같은 개념 정도는 정리해두셔야 시큐리티를 사용하고 싶을 때 관련 자료를 이해할 수 있답니다. 다음 토픽을 구글링해서 자료를 많이 읽어보시면 도움이 될 것 같습니다!

  • 인증 vs 인가
  • Filter란?
  • Spring Security는 어떻게 Filter를 활용하는가

[SpringBoot] Spring Security란?

 

[SpringBoot] Spring Security란?

대부분의 시스템에서는 회원의 관리를 하고 있고, 그에 따른 인증(Authentication)과 인가(Authorization)에 대한 처리를 해주어야 한다. Spring에서는 Spring Security라는 별도의 프레임워크에서 관련된 기능

mangkyu.tistory.com

한편으로.. 저도 아직 스프링 시큐리티 사용하는걸 너무 너무 어려워하는 사람으로서.. 아래 링크를 가볍게 읽어보시는걸 추천해요. 나중에 프로젝트하실 때 스프링 시큐리티 사용해서 로그인 구현하는 작업을 하다보면 정신이 아득해지는 경험을 할텐데요.. 너무 의기소침해지지 말고, 많이 써보고 읽어보면서 익숙해져봅시다. 홧팅!~

나의 스프링 시큐리티/JWT 해방일지

 

나의 스프링 시큐리티/JWT 해방일지

나는 왜 시큐리티를 유난히 어려워했나 / 여우가 추천하는 시큐리티 공부 자료 추천

velog.io

로그인 방식

이번 실습에서는 세션으로 유저 정보를 유지하는 세션 로그인을 구현해보았습니다. 로그인 방식에는 여러 방식이 있는데요, 큰 개념은 세션 및 쿠키를 사용하는 방식, 토큰을 사용하는 방식, 소셜 로그인을 사용하는 방식이 있습니다. 세션과 토큰은 대비되는 개념이고, 소셜 로그인은 리소스 서버로부터 데이터를 받아오는데 방점을 두기 때문에, 데이터를 받아온 이후에는 소셜 로그인이나 토큰 로그인 중 하나를 선택해 사용하시면 됩니다.

세션 방식과 인증 토큰 방식의 장단점을 애플리케이션의 종류에 따라 비교해보겠습니다. 웹 앱, 하이브리드 앱, 네이티브 앱의 개념이 생소하다면 이 링크를 읽고 와주세요!

100% 웹 앱에서는 세션 방식의 로그인이 잘 돌아갑니다. 브라우저가 쿠키 관리를 담당하므로, 세션 로그인 방식이 적합합니다.

하이브리드 앱에서는 세션 방식에 문제가 있습니다. 세션은 IP 단위로 유지되므로 와이파이 사용 등 IP 변경이 잦은 모바일 단말기에서는 세션이 자주 풀립니다. 또 쿠키를 관리하는 기능을 가진 브라우저를 사용하지 않으므로, 쿠키 id를 매번 주고 받지 않으면 세션을 유지할 수 없습니다. 또 세션 정보를 서버에 저장해야하므로 추가적인 저장 공간이 필요하죠. 이 경우에는 토큰 방식이 적합합니다. JWT는 인증에 필요한 정보를 암호화시킨 토큰인데요, 세션 방식보다 보안도 좋고 추가 저장소를 필요로 하지 않습니다. 또 문자열로 된 토큰만 보관하고 전달하면 되므로 다른 인증 시스템에 쉽게 확장할 수 있습니다.

네이티브 앱에서는 accessToken 개념을 적극적으로 사용합니다. 서버는 로그인 요청이 성공하면 클라이언트에게 해당 유저를 식별할 수 있는 accessToken을 부여헙니다. 클라이언트는 accessToken을 자신의 메모리에 보관했다가 서버에 API 요청을 할 때 활용합니다. 여기서 보안을 강화하려면 refresh token을 사용하여 만료 시간을 조정하는 방법도 있습니다.

모바일 앱을 구현하실 경우, JWT 방식의 로그인 구현은 필수입니다! 나중에 소셜 로그인과 연동도 해볼 수 있으니, 토이 프로젝트 주제로 추천드려요😎 아래 링크를 통해 로그인 방식이 어떠한 플로우로 진행되는지 파악해보시면 좋을 것 같아요.


❄️ 멤버들 추가공부 자료

'Group Study (2022-2023) > Spring 입문' 카테고리의 다른 글

6주차 레퍼런스  (0) 2023.01.12
5주차 레퍼런스  (0) 2023.01.12
3주차 레퍼런스  (0) 2023.01.12
2주차 레퍼런스  (0) 2023.01.12
1주차 레퍼런스  (0) 2023.01.12