Skip to content

Simple example of Spring Security oauth2Login, JWT, React SPA

Notifications You must be signed in to change notification settings

boyd-dev/demo-jwt

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 

Repository files navigation

스프링 시큐리티 oauth2Login + JWT + React

이 글은 스프링 MVC, 스프링 시큐리티를 사용하여 백엔드를, 리액트로 프론트엔드 애플리케이션을 만들어서 서로 데이터를 주고받는 방법에 관한 내용을 담고 있습니다(스프링 부트가 아닌 스프링 프레임워크를 사용합니다). 구조는 스프링 부트 기반의 예제와 매우 유사합니다. 차이는 리액트 SPA를 스프링 부트의 정적 리소스 위치에 넣었기 때문에 CORS 문제는 발생하지 않았다는 것입니다.

프론트엔드와 백엔드를 분리하는 것은 백엔드에서 JSP나 Thymeleaf 같은 템플릿 엔진을 사용하는 경우와 다릅니다. 템플릿 엔진을 사용하면 백엔드에서 뷰 페이지를 전부 생성하기 때문에 어떻게 보면 비교적 간단하다고 할 수 있습니다. 하지만 리액트와 같은 SPA 프론트엔드와 스프링 백엔드를 분리하는 경우는 여러 다양한 문제들을 겪게 됩니다.

  • CORS 문제
    CORS(Cross-Origin Resource Sharing)는 사용자가 원래 받은 리소스의 출처(origin)와 다른 URL로 요청을 보내고 그로부터 리소스가 전달되면 브라우저가 이를 막거나 허용하는 정책을 말합니다. 프론트엔드와 백엔드를 분리하면 프론트엔드(리액트 SPA) 서버와 백엔드 서버(스프링 MVC)는 서로 다른 URL을 가지고 있는 경우가 많고 따라서 프론트엔드 자바스크립트에서 백엔드 API를 호출하면 CORS 위반에 해당합니다. 어떻게 보면 당연히 되어야 할 것 같은데 브라우저가 이것을 못하게 막는 것입니다.

    이러한 경우에는 백엔드에서 보내는 응답의 헤더에 Access-Control-Allow-Origin=*을 설정하면 브라우저는 이 응답이 서버 측에서 "Resource Sharing" 한 것으로 판단하여 정상적으로 처리합니다. 백엔드 서버는 적어도 프론트엔드 애플리케이션에게 필요한 데이터를 대부분 보내주도록 개발했을 것이므로 CORS를 허용할 수 밖에 없습니다.

  • 세션없이 JWT 사용
    그런데 백엔드 서버의 API가 모두에게 공유된다면 문제가 있지 않을까요? 내가 개발한 프론트엔드가 호출하는 것은 가능하지만 다른 애플리케이션까지 허용해야 할까요? 프론트엔드 애플리케이션에 로그인한 사용자만 API를 호출할 수 있도록 하려면 어떻게 해야 할까요? 백엔드에서 모든 것을 처리하는 경우에는 세션정보가 있기 때문에 비교적 사용자 식별이 수월하지만 JWT를 인증 토큰으로 쓰는 경우는 세션을 만들지 않으므로 다른 방안이 필요합니다.

    이 예제에서는 인증을 하면 JWT를 발급하여 브라우저 쿠키에 저장하고, 이후 요청과 함께 전달되는 JWT를 검사하여 인증된 사용자를 식별할 것입니다. 이렇게 되면 백엔드 서버에서 JWT를 확인하여 유효한 경우에만 결과를 리턴하게 됩니다.

  • 구글 OAuth 2.0 인증 서비스
    이 예제에서는 사용자 가입절차 없이 사용자가 가진 구글 계정의 정보를 활용하여 인증을 처리하려고 합니다. 이를 위해 구글의 OAuth 2.0 인증 서비스를 이용할 것입니다. 구글에서 인증되었다면 그 정보를 바탕으로 JWT를 발급하여 쿠키에 저장합니다(구글이 발행하는 access token은 인증시점에 확인하는 용도로만 사용합니다).

예제 환경은 다음과 같습니다.

  • JDK 17
  • Spring MVC 5.3.32
  • Spring Security 5.8.10
  • Tomcat 9.0.87
  • Gradle 8.6
  • IDE - STS 4.20.1
  • react 18.2.0
  • react-router-dom 6.21.0

목차

  1. 백엔드 설정
  2. JWT 발급과 확인
  3. 프론트엔드