BackEnd/Spring Boot

Spring Boot 개발 중간 정리

Raconer 2023. 4. 15. 20:18
728x90

Spring Boot Api Server

Spec

  • Java : Temurin_11
  • Spring Boot : 2.6.7
  • Security
    • spring-security-web : 5.6.3
    • spring-security-config : 5.6.3
  • View
    • spring-boot-starter-thymeleaf : 2.7.2
  • DB
    • mysql-connector-java : 8.0.29
    • mybatis-spring-boot-starter : 2.2.2
    • HikariCP : 5.0.1
    • log4jdbc-log4j2-jdbc4.1 : 1.16
  • AWS
    • spring-cloud-starter-aws : 2.2.6.RELEASE
    • aws-java-sdk-ses : 1.12.276
  • 테스트
    • spring-boot-starter-test : 5.6.3
    • spring-security-test : 5.6.3
  • ETC
    • lombok:1.18.24
    • spring-boot-starter-validation : 2.7.2
    • commons-lang3 : 3.0
    • jjwt : 0.9.1

프로젝트 구조

  • Nuxt(nginX) <-> Spring Boot 통신 구조기본 셋팅
  • - src - main - java - com.project.structure - configuration - 설정 관련 ex) WebMvcConfigurer, Security, SES(Simple Email Service) etc.. - controller - cron - batch - filter - model - DTO, VO 용도로 사용 - repository - sql xml interface - utils - 공용 Enum 및 Code, Format - validate - resources - sql - template.email - application.properties - logback.xml
  • logback.xml
    • <configuration>
          <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
              <encoder>
                  <pattern>%d{yyyyMMdd HH:mm:ss.SSS} [%thread] %-3level %logger{5} - %msg %n</pattern>
              </encoder>
          </appender>
      
          <logger name="jdbc" level="OFF"/>
      
          <logger name="jdbc.sqlonly" level="OFF"/>
          <logger name="jdbc.sqltiming" level="DEBUG"/>
          <logger name="jdbc.audit" level="OFF"/>
          <logger name="jdbc.resultset" level="OFF"/>
          <logger name="jdbc.connection" level="OFF"/>
      
          <root level="INFO">
              <appender-ref ref="console" />
          </root>
      </configuration>
  • mybatis-config.xml
    • <configuration>
          <settings>
              <setting name="mapUnderscoreToCamelCase" value="true"/>
          </settings>
      
          <typeAliases>
          </typeAliases>
      
      </configuration>

사용자 토큰 인증

인증된 사용자만 API를 이용할수 있도록 토큰을 발급한다.

발급된 토큰은 Token과 Refresh Token 2가지 이다.

Token : 노출 되어도 크게 문제가 없는 데이터 만을 포함 하여 사용자 인증시 주로 사용되는 토큰이다.

RefreshToken : Token이 만료가 되면 RefreshToken을 사용하여 Token을 재 발급 받는 용도로 사용한다. 그래서 Token보다 Expired 기간이 길고 사용불가가 되면 보안을 위해 지우는 Token과 달리 RefreshToken안에는 아무런 사용자 데이터가 포함 되어 있지 않는다. 사용시에는 Refresh Token은 DB에 따로 저장을 하여 RefreshToken 인증후에 사용자를 찾아서 새로운 Token과 RefreshToken을 제공한다.

셋팅


기본 메소드

  • JWT UTILS
    • Create Token
    • Create Refresh Token
    • Verify Token
      • MalformedJwtException
      • ExpiredJwtException
      • UnsupportedJwtException
      • IllegalArgumentException
      • SignatureException
      • Exception
    • Convert User Info(token -> userInfo)
  • Filter
    • JwtAuthenticationEntryPoint
      • exceptionHandling : 토큰 인증 오류시 실행
      •   @Component
          public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
               @Override
              public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
                  // 사용자 인증 예외 처리
              }
          }
    • jwtRequestFilter
      • 토큰 인증 필터 API 접근시 동작
      •   @Component
          public class JwtRequestFilter extends OncePerRequestFilter {
        
              private static final List<String> EXCLUDE_URL =
                          Collections.unmodifiableList(
                                  Arrays.asList(
                                          "/login"
                                  ));
        
              @Override
              protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
                  ...
                  // 토큰 인증 및 사용자 데이터 셋팅(용도에 따라 코드 수정 필수) 
                  UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user, null ,user.getAuthorities());
                  authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                  // 사용자 데이터를 셋팅하면 @AuthenticationPrincipal 어노테이션으로 User 정보를 가져올수있다.
                  SecurityContextHolder.getContext().setAuthentication(authenticationToken);
                  filterChain.doFilter(request,response);
              }
        
              @Override
              protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
                  // 토큰 인증이 필요 없을때
                  return EXCLUDE_URL.stream().anyMatch(exclude -> exclude.equalsIgnoreCase(request.getServletPath()));
              }
          }

Config Setting

  • Security Config
  • @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { ... @Override protected void configure(HttpSecurity http) throws Exception { http ... // 토큰 인증 예외 처리 .and() .exceptionHandling() .authenticationEntryPoint(jwtAuthenticationEntryPoint) ... ; // 사용자 인증 Filter 전에 동작 http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class); } ... }

application.properties 셋팅

database

spring.datasource.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.datasource.url=jdbc:log4jdbc:mysql://localhost:3306/db_table?allowMultiQueries=true&characterEncoding=utf8&useTimezone=true&serverTimezone=UTC
spring.datasource.username=username
spring.datasource.password=password

mybatis

mybatis.mapper-locations=classpath:sql//.xml
mybatis.type-aliases-package=com.project.structure.model.*
mybatis.config-location=classpath:sql/mybatis-config.xml

spring.datasource.hikari.connectionTimeout = 30000
spring.datasource.hikari.maximumPoolSize = 10
spring.datasource.hikari.maxLifetime = 1800000
spring.datasource.hikari.readOnly = false

Upload File Size

spring.servlet.multipart.file-size-threshold=100MB
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=100MB

Spring Thymeleaf

spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML
spring.thymeleaf.encoding=UTF-8


추가 기능

Schedule

특정 시간대에 메소드가 실행 되게 하는 기능

  @Component
  public class ExampleCron {

      // @Scheduled(cron = "0 0 0 * * *")    // 자정
      // @Scheduled(cron = "*/10 * * * * *") // 10초마다
      public void run() {
          System.out.println("메소드 실행");
      }
  }

Cacheable

Spring Boot 기능중에 Cache 어노테이션이 있다.
이 기능은 자주 변경 되지 않는 DB내용을 캐쉬에 저장 한 후에 사용을 하며
사용을 하게 되면 불필요한 DB Connect를 하지 않아 DB 부담을 줄일수있다.
주로 Service 에서 사용을 하며 데이터 수정시 cache update를 해야한다.

사용법

  • @Cacheable
    • Create, Read
    •   @Cacheable(value = "userDetail", key = "#userId")
        public UserDetailsDto findUserDetails(Long userId) {
      
            로직 처리...
      
            UserDetailsDto result = UserDetailsDto.builder()
                    ...
                    .build();
      
            return result;
        }
  • @CachePut
    • Update
    •   @CachePut(value = "userDetail", key = "#updateUserDto.id")
        public UserDetailsDto updateProfile(UpdateUserDto updateUserDto) {
      
            로직 처리...
      
            return UserDetailsDto.builder()
                    ...
                    .build();
        }
  • @CacheEvict
    • Delete
    •   @CacheEvict(value = "userDetail", key = "#userId")
        public void deleteUser(Long userId) {
            로직 처리...
        }

참조

[1]Temurin란?

[2]Cacheable

728x90

'BackEnd > Spring Boot' 카테고리의 다른 글

War VS Jar  (0) 2023.04.16
AOP란?  (0) 2023.04.15
Spring boot Test Case  (0) 2023.04.15
Spring Request Flow  (0) 2023.04.15
Token JJWT  (0) 2023.04.15