Spring boot와 React에서의 OAuth2

세민·2023년 9월 12일

Spring boot

목록 보기
1/1
post-thumbnail

개요

이번에 프로젝트를 진행하면서 Spring boot에서 Discord와 OAuth2를 같이 사용하여 로그인기능을 구현해야하는 일이 있었다.
이 과정에서 어떻게 요구사항에 맞춰 구조를 설계하였고 문제해결을 했는지에 대한 기록을 남기기 위해서 글을 작성하게 되었다!

기술스택

[FrontEnd]

* React
* tailwindcss

[BackEnd]

* Spring boot
* MariaDB

[BackEnd Dependency]

* spring-security-oauth2-client
* spring-boot-starter-security
* spring-boot-starter-web
* mybatis-spring-boot-starter
* mariadb-java-client
* lombok

설계

프로젝트의 내용은 구글폼을 디스코드 계정을 사용하여 폼을 이용할 수 있도록 하는것인데, 즉 구글폼을 클론코딩하되 구글계정이 아닌 디스코드 계정을 이용하여 로그인 및 사용자정보를 이용해야 하는것이다.

웹사이트의 처음은 로그인화면이며 로그인버튼을 누르면 디스코드의 OAuth2 API를 이용해서 디스코드로 리다이렉트되면 거기서 로그인을 진행하고 로그인이 완료된다면 다시 웹사이트로 돌아와 디스코드에서 넘겨준 로그인성공/사용자정보를 받아와 폼제출 화면을 띄우도록 프레임을 잡고 진행을 했다.

본문

이 글의 주제인 OAuth2부터 살펴보자면 Spring boot에서 Spring security와 Discord Provider를 이용해 로그인 시스템을 구현하는것은 여기를 참고했다.

백엔드단에서 로그인 기능은 구현이 되었는데...

어떤것이 문제가 되었을까?

Spring boot에서 template와 thymeleaf등을 이용하여 프론트를 구현한것이 아닌, React를 사용하여 구현한 것이 문제의 시발점이었다.

필자는 이 프로젝트가 Spring boot를 사용한 두번쨰 프로젝트였으며, 당연하게도 Spring boot와 React를 같이 사용해본적이 없었다.

이제 두번쨰로 Spring boot에서 OAuth2가 어떻게 작동하는지 이해해보자면

  1. localhost:8080/oauth2/authorization/discord로 접속, discord의 로그인 페이지로 리다이렉트 된다.
  2. discord의 로그인 페이지에서 로그인을 진행, 완료되면 다시 백엔드 주소로 리다이렉트 된다. (백엔드 주소는 설정가능)
  3. 백엔드에서는 로그인정보와 사용자 접속정보를 이용하여 OAuth2AccessTokenResponse를 생성한다.

여기서 문제가 React와 Spring boot의 실행 포트가 달라서 CORS문제가 발생하기에 Proxy를 이용하여 React에서 Spring boot를 연결시키는데 이렇게되면 리엑트단에서 /oauth2.authorization/discord로 리다이렉트 시키는게 아닌 localhost:8080/oauth2/authorization/discord로 리다이렉트 시켜야하고 백엔드단에서도 로그인 성공시 localhost:3000//로그인성공페이지로 리다이렉트 시켜야하기에 유지보수면에서 그닥 좋지 않은 방법이었다.

해결방법?

React, Spring boot모두 .env, properties를 사용하여 경로를 변수형식으로 관리하여 유지보수, 설계적인 측면에서 모두 만족할만한 결과를 도출해냈다.

이 방법이 틀린 방법일 수도 있다.

[BackEnd] (application.yml의 일부)

custom-properties:
  loginSuccessUrl: http://localhost:3000/join
  loginFailureUrl: http://localhost:3000/login

[FrontEnd] (.env의 일부)

REACT_APP_BACKEND_URL=http://localhost:8080

백엔드단에서는 아래의 코드와 같이 OAuth2 성공/실패 Handler를 통해 각각 다른 URL로 리다이렉트 하게끔 설계하였고

@Bean
SimpleUrlAuthenticationSuccessHandler oauth2SuccessHandler() {
    return new SimpleUrlAuthenticationSuccessHandler(loginSuccessUrl);
}

@Bean
SimpleUrlAuthenticationFailureHandler oauth2FailureHandler() {
    return new SimpleUrlAuthenticationFailureHandler(loginFailureUrl);
}

프론트단에서는 아래의 코드와 같이 REACT_APP_BACKEND_URL를 가져와 backendUrl에 전역변수로 등록하고 Link 컴포넌트를 이용하여 다음과 같은 URL로 리다이렉트 하게끔 설계하였다.

<Link to={`${backendUrl}/oauth2/authorization/discord`} className="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded text-center">
    디스코드로 로그인하기
</Link>

마무리

이번 프로젝트를 통해 전체적인 Spring boot의 사용법, 개념등을 익힐 수 있었고, React와 Spring boot를 같이 사용하는법, 부가적으로 MyBatis사용법 또한 익힐 수 있었다.

profile
개발자가 꿈이에요

0개의 댓글