인프런 커뮤니티 질문&답변

junuuu님의 프로필 이미지
junuuu

작성한 질문수

스프링 시큐리티 OAuth2

OAuth 2.0 Authorization Grant Code 네이버 로그인 구현

작성

·

1K

·

수정됨

1

안녕하세요 정수원님 강의 내용과 조금 다른 부분이긴한데 질문드리고자 합니다.

VueSpring Boot(Spring Security OAuth Client로 활용)로 네이버 로그인을 구현해보고 있습니다.

웹, 안드로이드, iOS 등에 대한 소셜로그인을 Authorization Grant Code방식으로 구현하려고 하고 있으며 REST API 방식으로 동작하도록 하고싶습니다.

하지만 Spring Securityorg.springframework.boot:spring-boot-starter-oauth2-client 의존성을 추가하여 OAuth2UserService를 구현하게되면 백엔드에 your-server-host/ oauth2/authorization/naver로 요청을 보내면 사용자에게 로그인을 받고 Authorization Grant Code를 받아와 AccessToken을 반환받고 이를 통해 UserInfoResource Server로부터 받아오는 과정을 처리해줍니다.

이 과정속에서 프론트에게 로그인 성공시 실행되는 AuthenticationSuccessHandler 구현 과정에서 sendRedirect를 통해 accessTokenrefreshToken을 전달하려고 했으나 이런 방식은 REST API에 적합하지 않은것 같다고 느껴집니다.

심지어 front에서 버튼을 클릭하면 GET 요청으로 /oauth2/authorization/naver를 호출하도록 해보려고 했으나 이 경우에 네이버 로그인 호출하는 과정에서 CORS에러가 발견되어 하이퍼링크로 호출하도록 구현하였습니다.

 

위의 배경으로 궁금한 점은 다음과 같습니다.

  • 프론트엔드와 Authorization Grant CodeREST API 방식으로 구현하기 위해서는 어떻게 해야할까요? 제가 생각한 방식과 굉장히 유사한 블로그 포스팅을 발견했는데 Spring Security는 사용하지 않는 것 같습니다.(https://blog.naver.com/PostView.naver?blogId=varkiry05&logNo=222295764870) Spring Security를 활용하는 방안이 있다면 추천 부탁드립니다.. 혹은 굳이 Spring Security를 사용하지 않고 구현해도 된다고 생각하시는경우에도 의견주시면 감사하겠습니다.

  • 위의 경우에는 client-id를 프론트에서 관리하며 강좌에서 이런 경우에는 보안상의 이슈가 발생할 수 있다고 하셨는데 어떻게 대안점이 있을까요? (https://www.rfc-editor.org/rfc/rfc6749#section-2.3.1) rfc6749에서는 client-id는 secret이 아니라고 하는것 같습니다.

  •  제가 처음 구현하려던 방식과 유사한 tech blog를 찾았습니다. 내부적인 커스터마이징을 통해 redirection을 구현한 것 같습니다.(https://tech.kakao.com/2023/01/19/social-login/) 이때 accessToken과 refreshToken을 redirect시킬 때 param으로 넘긴다면 url주소로 토근값들이 보일것인데 보안상으로 괜찮을까요?

 

ps.

실제로 https://olive.kakao.com/login (카카오 테크 블로그에 소개된 redirection이 구현된 페이지)의 js 코드를 까보니 <a> 태그 형식의 하이퍼링크로 호출함을 확인했으며, redirect되는 callback url에서 token값을 확인할 수 있음을 크롬 개발자도구 네트워크탭에서 확인했습니다.

  

감사합니다.

답변 1

3

정수원님의 프로필 이미지
정수원
지식공유자

스프링 시큐리티의 Client 모듈은 기본적으로는 서버사이드 웹에 최적화 되어 있습니다.

물론 모바일이나 프론트앱에서도 활용은 가능합니다.

Authorization Code Grant 방식을 사용함에 있어 두 단계로 나누어 집니다.

첫번째는 임시코드를 가지고 오기 위한 단계이며

두번째는 토큰을 가지고 오기 위한 단계입니다.

토큰을 가지고 사용자 정보를 가지고 오는 것은 Authorization Code Grant 방식과는 무관합니다

OAuth2 의 궁극적인 목적은 클라이언트의 권한 획득 즉 Access Token 을 획득하는 것이기 때문입니다.

여기서 임시코드를 가지고 오기 위해서 인증서버로 요청을 하고 응답받는 과정은 프론트 채널에서 이루어집니다.

그래서 client id 와 redirect_uri, scope 등의 정보를 전달하고 인증서버로부터 리다이렉션 되면서 임시코드를 받아오게 됩니다. 이부분은 반드시 스프링 시큐리티의 Client 모듈을 사용하지 않고 JS 로 구현하셔도 됩니다.
임시코드 요청 때는 client_secret 이 전달되는 것은 아니기 때문입니다.
그리고 임시코드를 가지고 토큰을 가지고 올 때는 백채널에서 요청과 응답이 이루어져야 하기 때문에 스프링 시큐리티의 Client 모듈을 사용하면 됩니다. 백채널에서 처리가 이루어지기 때문에 client_secret 를 인증서버로 전달하더라도 보안상 안전합니다.
다만 이 같은 경우 어느 정도의 커스트 마이징이 필요합니다. 왜냐하면 스프링 시큐리티는 임시코드를 요청하는 필터와 토큰을 요청하는 필터가 각각 존재하는데 만약 임시코드 처리를 JS 로 구현하고 토큰 요청처리를 시큐리티를 사용한다면 토큰 처리 필터만 작동하도록 커스트 마이징되어야 합니다.

일반적으로 프론트에서 Rest 로 Authorization Code Grant 요청을 하게 된다면 임시코드 발급 > 토큰 발급 > 사용자 정보 조회 > 인증처리 한 다음 successHandler 와 같은 곳에서 최종 이동할 페이지로 리다이렉트 해서 화면을 보여주게 됩니다. 물론 이 흐름은 실행 환경이나 상황에 따라 여러형태로 구현될 수 있습니다.

AuthenticationSuccessHandler 구현 과정에서 sendRedirect를 통해 accessTokenrefreshToken을 전달하려고 했으나 이런 방식은 REST API에 적합하지 않은것 같다고 하셨는데 임시토큰 요청은 리다이렉션이 반드시 수행되어야 하며 이후 토큰교환 및 사용자 정보와 인증처리는 클라이언트 백채널과 인증서버간에 이루어지기 때문에 REST API 방식으로 스프링 시큐리티 OAuth2 Client 모듈을 사용할 경우 최초 클라이언트의 요청과 최종 서버의 응답 간 흐름을 잘 파악해서 구현해야 합니다.

시큐리티의 모든 기능을 다 사용할 필요는 없지만 시큐리티가 Authorization Code Grant 방식을 어떻게 처리하는지 구조와 흐름들을 알게 된다면 꼭 필요한 부분만 커스트마이징 해서 사용할 수 있고 기존 클래스를 확장해서 사용할 수도 있습니다.

혹 현재 구현하고 있는 소스가 있으면 제가 확인해 볼 수는 있을 것 같습니다.

junuuu님의 프로필 이미지
junuuu
질문자

답변 감사드립니다!!!

junuuu님의 프로필 이미지
junuuu

작성한 질문수

질문하기