1. 문제 상황
분명히 프로젝트에는 회원가입과 로그인 요청 API는 인증하지 않는다고 SecurityConfig에 선언해뒀다.
그리고, 원하는 대로 잘 동작했다.
그런데, 어느 순간 회원가입이 정상적으로 처리되지 않는 상황이 발생했다.
아래 처럼

2. 원인 찾기
2 - 1. 팀 공통 깃허브 레포에서 병합하는 과정에서 발생한 문제?
처음에는 팀 공통 레포에서 pull 당긴 후에 벌어진 일이라
병합하는 과정에서 뭔가 충돌이 있었겠거니 했다.
팀원들에게 물어본 결과, 문제가 없다는 답변을 받았다.
같은 레포를 pull 당겼는데 나만 문제가 생길 수가 있나?
2 - 2. SecurityConfig 를 다시 한 번 살펴보기
package com.sparta.project.config;
import com.sparta.project.config.jwt.JwtAuthenticationFilter;
import com.sparta.project.exception.CustomAccessDeniedHandler;
import com.sparta.project.exception.CustomAuthenticationEntryPoint;
import lombok.RequiredArgsConstructor;
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.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@RequiredArgsConstructor
@EnableWebSecurity
public class SecurityConfig {
private final JwtAuthenticationFilter jwtAuthenticationFilter;
private final CustomAuthenticationEntryPoint customAuthenticationEntryPoint;
private final CustomAccessDeniedHandler customAccessDeniedHandler;
private final String[] permitPaths = {
"/users/login",
"/users/signup",
};
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf(AbstractHttpConfigurer::disable)
.formLogin(AbstractHttpConfigurer::disable)
.httpBasic(AbstractHttpConfigurer::disable)
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.exceptionHandling(exception-> {
exception.authenticationEntryPoint(customAuthenticationEntryPoint);
exception.accessDeniedHandler(customAccessDeniedHandler);
});
http.authorizeHttpRequests(auth -> {
auth.requestMatchers(permitPaths).permitAll();
auth.anyRequest().authenticated();
}).addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedOriginPatterns("*")
.allowedMethods("*");
}
};
}
}
permitPaths들은 permitAll() 해줬으니 인증 없이 통과가 되어야 하는 게 맞다.
SecurityConfig 문제는 아닌 듯 하다.
2 - 3. 에러 로그 확인
org.postgresql.util.PSQLException: ERROR: value too long for type character varying(10)
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2733) ~[postgresql-42.7.4.jar:42.7.4]
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2420) ~[postgresql-42.7.4.jar:42.7.4]
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:372) ~[postgresql-42.7.4.jar:42.7.4]
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:517) ~[postgresql-42.7.4.jar:42.7.4]
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:434) ~[postgresql-42.7.4.jar:42.7.4]
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:194) ~[postgresql-42.7.4.jar:42.7.4]
at org.postgresql.jdbc.PgPreparedStatement.execute(PgPreparedStatement.java:180) ~[postgresql-42.7.4.jar:42.7.4]
at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44) ~[HikariCP-5.1.0.jar:na]
10글자 보다 많이 들어가서 DB에 쓰기 작업이 안되고 있다라...
요청한 데이터는 10글자가 넘어가지 않는데?
### 회원가입
POST localhost:8080/users/signup
Content-Type: application/json
{
"username" : "testName",
"password" : "1234",
"nickname": "cute",
"role" : "CUSTOMER"
}
3. 문제 원인 파악 완료 - AuditorAwareImpl
어제 구현했던 AuditorAwareImpl이 문제를 일으키는 것 같다.
@Slf4j
public class AuditorAwareImpl implements AuditorAware<String> {
@Override
public Optional<String> getCurrentAuditor() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (null == authentication || !authentication.isAuthenticated()) {
return null;
}
//사용자 환경에 맞게 로그인한 사용자의 정보를 불러온다.
return Optional.of(authentication.getName());
}
}
아무리 봐도 얘밖에 없다.
그래서, 구현한 AuditorAwareImpl 과 @JpaAuditing 기능을 주석 처리하고 회원가입을 시도했더니
정상적으로 회원가입이 되었다!!!
생각해보면, jwt 토큰 없이 요청하는 회원가입이나 로그인은 생성을 요청한 사람을 기재할 수가 없겠다.
그리고 또 궁금한 점! 왜 10글자를 넘긴다고 에러가 떴을까? 어떤 값이 들어갈까?
로그를 찍어보았다.
log.info("authentication.getName(): {}", authentication.getName());
결과는

anonymousUser 라는 문자열이 들어가서 문제가 발생했던 거구나...
그러면, 회원가입처럼 유저 정보를 확인할 방법이 없는 경우 anonymous만 넣어주자
@Slf4j
public class AuditorAwareImpl implements AuditorAware<String> {
@Override
public Optional<String> getCurrentAuditor() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (null == authentication || !authentication.isAuthenticated()) {
return null;
}
//사용자 환경에 맞게 로그인한 사용자의 정보를 불러온다.
log.info("authentication.getName(): {}", authentication.getName());
if (authentication.getName().equals("anonymousUser")) {
return Optional.of("anonymous");
}
return Optional.of(authentication.getName());
}
}
4. 결과

정상적으로 회원가입이 되고 created_by와 updated_by도 anonymous가 들어간 걸 확인했다.
'자바 심화 2기' 카테고리의 다른 글
CodeBloom - AI를 활용한 주문 관리 플랫폼 프로젝트 결과물 (1) | 2024.11.19 |
---|---|
2024 11 14 TIL - Spring Data의 @PageableDefault, @SortDefault (0) | 2024.11.14 |
2024 11 13 TIL - QueryDSL, BooleanExpression (1) | 2024.11.13 |
2024 11 11 TIL - AuditorAware 구현하기 (2) | 2024.11.11 |
[Spring 심화 2기] 9팀 코드블룸 - CH.1 AI 검증 비즈니스 프로젝트 S.A (0) | 2024.11.07 |
1. 문제 상황
분명히 프로젝트에는 회원가입과 로그인 요청 API는 인증하지 않는다고 SecurityConfig에 선언해뒀다.
그리고, 원하는 대로 잘 동작했다.
그런데, 어느 순간 회원가입이 정상적으로 처리되지 않는 상황이 발생했다.
아래 처럼

2. 원인 찾기
2 - 1. 팀 공통 깃허브 레포에서 병합하는 과정에서 발생한 문제?
처음에는 팀 공통 레포에서 pull 당긴 후에 벌어진 일이라
병합하는 과정에서 뭔가 충돌이 있었겠거니 했다.
팀원들에게 물어본 결과, 문제가 없다는 답변을 받았다.
같은 레포를 pull 당겼는데 나만 문제가 생길 수가 있나?
2 - 2. SecurityConfig 를 다시 한 번 살펴보기
package com.sparta.project.config;
import com.sparta.project.config.jwt.JwtAuthenticationFilter;
import com.sparta.project.exception.CustomAccessDeniedHandler;
import com.sparta.project.exception.CustomAuthenticationEntryPoint;
import lombok.RequiredArgsConstructor;
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.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@RequiredArgsConstructor
@EnableWebSecurity
public class SecurityConfig {
private final JwtAuthenticationFilter jwtAuthenticationFilter;
private final CustomAuthenticationEntryPoint customAuthenticationEntryPoint;
private final CustomAccessDeniedHandler customAccessDeniedHandler;
private final String[] permitPaths = {
"/users/login",
"/users/signup",
};
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf(AbstractHttpConfigurer::disable)
.formLogin(AbstractHttpConfigurer::disable)
.httpBasic(AbstractHttpConfigurer::disable)
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.exceptionHandling(exception-> {
exception.authenticationEntryPoint(customAuthenticationEntryPoint);
exception.accessDeniedHandler(customAccessDeniedHandler);
});
http.authorizeHttpRequests(auth -> {
auth.requestMatchers(permitPaths).permitAll();
auth.anyRequest().authenticated();
}).addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedOriginPatterns("*")
.allowedMethods("*");
}
};
}
}
permitPaths들은 permitAll() 해줬으니 인증 없이 통과가 되어야 하는 게 맞다.
SecurityConfig 문제는 아닌 듯 하다.
2 - 3. 에러 로그 확인
org.postgresql.util.PSQLException: ERROR: value too long for type character varying(10)
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2733) ~[postgresql-42.7.4.jar:42.7.4]
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2420) ~[postgresql-42.7.4.jar:42.7.4]
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:372) ~[postgresql-42.7.4.jar:42.7.4]
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:517) ~[postgresql-42.7.4.jar:42.7.4]
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:434) ~[postgresql-42.7.4.jar:42.7.4]
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:194) ~[postgresql-42.7.4.jar:42.7.4]
at org.postgresql.jdbc.PgPreparedStatement.execute(PgPreparedStatement.java:180) ~[postgresql-42.7.4.jar:42.7.4]
at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44) ~[HikariCP-5.1.0.jar:na]
10글자 보다 많이 들어가서 DB에 쓰기 작업이 안되고 있다라...
요청한 데이터는 10글자가 넘어가지 않는데?
### 회원가입
POST localhost:8080/users/signup
Content-Type: application/json
{
"username" : "testName",
"password" : "1234",
"nickname": "cute",
"role" : "CUSTOMER"
}
3. 문제 원인 파악 완료 - AuditorAwareImpl
어제 구현했던 AuditorAwareImpl이 문제를 일으키는 것 같다.
@Slf4j
public class AuditorAwareImpl implements AuditorAware<String> {
@Override
public Optional<String> getCurrentAuditor() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (null == authentication || !authentication.isAuthenticated()) {
return null;
}
//사용자 환경에 맞게 로그인한 사용자의 정보를 불러온다.
return Optional.of(authentication.getName());
}
}
아무리 봐도 얘밖에 없다.
그래서, 구현한 AuditorAwareImpl 과 @JpaAuditing 기능을 주석 처리하고 회원가입을 시도했더니
정상적으로 회원가입이 되었다!!!
생각해보면, jwt 토큰 없이 요청하는 회원가입이나 로그인은 생성을 요청한 사람을 기재할 수가 없겠다.
그리고 또 궁금한 점! 왜 10글자를 넘긴다고 에러가 떴을까? 어떤 값이 들어갈까?
로그를 찍어보았다.
log.info("authentication.getName(): {}", authentication.getName());
결과는

anonymousUser 라는 문자열이 들어가서 문제가 발생했던 거구나...
그러면, 회원가입처럼 유저 정보를 확인할 방법이 없는 경우 anonymous만 넣어주자
@Slf4j
public class AuditorAwareImpl implements AuditorAware<String> {
@Override
public Optional<String> getCurrentAuditor() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (null == authentication || !authentication.isAuthenticated()) {
return null;
}
//사용자 환경에 맞게 로그인한 사용자의 정보를 불러온다.
log.info("authentication.getName(): {}", authentication.getName());
if (authentication.getName().equals("anonymousUser")) {
return Optional.of("anonymous");
}
return Optional.of(authentication.getName());
}
}
4. 결과

정상적으로 회원가입이 되고 created_by와 updated_by도 anonymous가 들어간 걸 확인했다.
'자바 심화 2기' 카테고리의 다른 글
CodeBloom - AI를 활용한 주문 관리 플랫폼 프로젝트 결과물 (1) | 2024.11.19 |
---|---|
2024 11 14 TIL - Spring Data의 @PageableDefault, @SortDefault (0) | 2024.11.14 |
2024 11 13 TIL - QueryDSL, BooleanExpression (1) | 2024.11.13 |
2024 11 11 TIL - AuditorAware 구현하기 (2) | 2024.11.11 |
[Spring 심화 2기] 9팀 코드블룸 - CH.1 AI 검증 비즈니스 프로젝트 S.A (0) | 2024.11.07 |