본문 바로가기
개발/Security

[SpringBoot] React + Security + JWT (1) - 한번에 Build 하기

by 코딩하는 흰둥이 2024. 11. 28.

https://greed-yb.tistory.com/303

 

[SpringBoot] React + TypeScript + JPA 프로젝트 (1) - 생성

Java 17GradleSpring Boot 3.3.4Spring Security 6.3.3Oracle 11gIntelliJ UltimateDBeaverReactJPASpringBoot 프로젝트 생성   프로젝트 생성이 끝나면 properties 파일이 생성된다 server.port= 7172# Databasespring.datasource.driver-class-n

greed-yb.tistory.com

https://greed-yb.tistory.com/305

 

[SpringBoot] React + TypeScript + JPA 프로젝트 (3) - SpringSecurity 적용

이전글https://greed-yb.tistory.com/304 [SpringBoot] React + TypeScript + JPA 프로젝트 (2) - Bootstrap 적용이전글https://greed-yb.tistory.com/303 [SpringBoot] React + TypeScript + JPA 프로젝트 (1) - 생성Java 17GradleSprinb Boot 3.3.4Spri

greed-yb.tistory.com

 

 

이전글에서

React + Security 를 적용한 프로젝트를 한 번에

Build 하여 실행시키려고 하니 

설정에 문제가 있는지 페이지가 실행되지 않아 각각 실행하였었다

 

그로 인해서 JWT Token 을 적용하였음에도 Security 에서 사용을 못하고

React 화면단에서 JWT Token 을 인증하였었는데

이번에 한번에 Build 를 시키며 Security 에서도 인증/인가를 적용하려고 한다

 

 

 

 

 

환경
  • Java 17
  • Gradle
  • Spring Boot 3.3.4
  • Spring Security 6.3.3
  • Oracle 11g
  • IntelliJ Ultimate
  • DBeaver
  • React 18.3.1
  • JPA 

 

 

 

WebSecurityConfig
package com.example.reactpractice.security;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;


@EnableWebSecurity
@Configuration
public class WebSecurityConfig {
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.addAllowedOrigin("http://localhost:3000"); // React 주소
        configuration.addAllowedOrigin("http://localhost:7172"); // SpringBoot 주소
        configuration.addAllowedMethod("*"); // 모든 HTTP 메서드 허용
        configuration.addAllowedHeader("*"); // 모든 헤더 허용
        configuration.setAllowCredentials(true); // 인증 정보 포함 (쿠키 기반)

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }


    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        http
                .cors().configurationSource(corsConfigurationSource()).and()
                .csrf().disable()
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/","/index.html","/{path:[^\\.]*}","/resources/**", "/static/**", "/assets/**" , "/css/**", "/js/**").permitAll() // 정적 리소스 허용
                        .requestMatchers("/api/**").permitAll() //axios 허용
                        .anyRequest().authenticated() // 나머지 요청은 인증 필요
                )
                .httpBasic().disable()  // 기본 HTTP 인증 비활성화
                .formLogin().disable(); // 폼 기반 인증 비활성화
        return http.build();
    }
}

 

"/" 와 "/index.html" , CSS , JS 경로를 지정한다

 

 

 

이전글에서는 

security 설정할 때 Cors 설정을 @Configuration 으로 했었는데

이번엔 Security 설정 안에 같이 넣었다

 

 

 

 

application.properties

# React CSS/JS 제공
spring.web.resources.static-locations=classpath:/static/

 

정적 리소스 경로를 설정해준다

 

build.gradle
// React root 경로
def frontendDir = "$projectDir/src/main/frontend"

sourceSets {
    main {
        resources { srcDirs = ["$projectDir/src/main/resources"]
        }
    }
}

processResources { dependsOn "copyReactBuildFiles" }

task installReact(type: Exec) {
    workingDir "$frontendDir"
    inputs.dir "$frontendDir"
    group = BasePlugin.BUILD_GROUP
    if (System.getProperty('os.name').toLowerCase(Locale.ROOT).contains('windows')) {
        commandLine "npm.cmd", "audit", "fix"
        commandLine 'npm.cmd', 'install' }
    else {
        commandLine "npm", "audit", "fix" commandLine 'npm', 'install'
    }
}

task buildReact(type: Exec) {
    dependsOn "installReact"
    workingDir "$frontendDir"
    inputs.dir "$frontendDir"
    group = BasePlugin.BUILD_GROUP
    if (System.getProperty('os.name').toLowerCase(Locale.ROOT).contains('windows')) {
        commandLine "npm.cmd", "run-script", "build"
    } else {
        commandLine "npm", "run-script", "build"
    }
}

task copyReactBuildFiles(type: Copy) {
    dependsOn "buildReact"
    from "$frontendDir/build"                       // React build 파일 위치
    into "$projectDir/src/main/resources/static"    // React build 파일을 해당 경로로 복사하겠다
}

 

이전과 동일하다

build.gradle 아래에 위의 코드를 붙여 넣고 본인의 프로젝트 경로에 맞게 수정하자

 

 

 

 

package.json

 

homepage 경로를 설정해 준다

설정하지 않으면 Default"/" 가 되는데

localhost:xxxx 일 때는 문제가 없지만

다른 경로를 사용할 때 CSS/JS 문제가 생길 수 도 있어서 설정해 놓는다

 

 

 

 

Controller
@Controller
public class WebController {

    // 모든 비정적 경로 처리하며 React의 index.html 로 이동시킨다
    @GetMapping("/{path:[^\\.]*}")
    public String forward() {
        return "forward:/index.html";
    }
}

 

화면 이동은 React 에서 실행되나

Security 설정이 되어 있기 때문에 server 에서도 

build 된 index.html 로 이동하는 코드가 필요하다

 

 

 

 

TEST

각각 실행이 아닌 IDE 에서 실행을 하자

 

 

3000 포트가 아닌

SpringBoot 7172 포트로 실행되었다

 

 

 

 


 

현재 글은 Security 가 적용된 상태에서 

gradle 을 한 번에 Build 하여 실행하는 방법만 작성하였다

JWT Token 및 인증인가 에 대한 내용은 다음글에서 다뤄보겠다

댓글