본문 바로가기
스프링

스프링 - 스프링 시큐리티를 이용한 로그인 구현하기 (1)

by 개발자 포비 2024. 12. 15.

Spring Security와 React 인증 구현 정리

스프링 부트와 리액트틀 이용하여 서버 - 클라이언트 구조를 만들고, 스프링 시큐리티를 이용하여 로그인하는 기능을 만든다. 내용이 방대하기 때문에 천천히 하나씩 설명해나가려고 한다. 우선 전체적인 느낌만 살펴본다.

1. 기본 설정

SecurityConfig 설정

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .cors(cors -> cors.configurationSource(corsConfigurationSource()))
            .csrf(csrf -> csrf.disable())
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/v1/products").permitAll()
                .requestMatchers("/api/v1/orders/**").authenticated()
                .requestMatchers("/api/v1/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            );
        return http.build();
    }
}

CORS 설정

@Bean
public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000"));
    configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
    configuration.setAllowedHeaders(Arrays.asList("*"));
    configuration.setAllowCredentials(true);

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

2. 사용자 인증 처리

CustomUserDetailsService

@Service
public class CustomUserDetailsService implements UserDetailsService {
    @Override
    public UserDetails loadUserByUsername(String username) {
        User user = userRepository.findByUsername(username)
            .orElseThrow(() -> new UsernameNotFoundException("User not found"));

        return org.springframework.security.core.userdetails.User.builder()
            .username(user.getUsername())
            .password(user.getPassword())
            .roles(user.getRole().name())
            .build();
    }
}

3. 인증 흐름 순서

  1. 사용자가 React 앱에서 로그인 시도
  2. Spring Security의 인증 필터가 요청 처리
  3. CustomUserDetailsService가 사용자 정보 로드
  4. 비밀번호 검증 (PasswordEncoder 사용)
  5. 인증 성공/실패 응답 전송

4. React에서의 구현

로그인 컴포넌트

function LoginForm() {
    const [username, setUsername] = useState('');
    const [password, setPassword] = useState('');

    const handleSubmit = async (e) => {
        e.preventDefault();
        try {
            const response = await fetch('/login-process', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: `username=${username}&password=${password}`,
                credentials: 'include'
            });
            if (response.ok) {
                // 로그인 성공 처리
            }
        } catch (error) {
            // 에러 처리
        }
    };
}

권한에 따른 UI 렌더링

function Dashboard() {
    const [userInfo, setUserInfo] = useState(null);

    useEffect(() => {
        axios.get('/api/user-info')
            .then(response => setUserInfo(response.data));
    }, []);

    return (
        <div>
            {userInfo?.role === 'ROLE_ADMIN' && (
                <button>관리자 기능</button>
            )}
        </div>
    );
}

5. 보안 고려사항

  • HTTPS 사용 권장
  • CSRF 보호 설정
  • 적절한 비밀번호 인코딩
  • 세션 관리
  • 권한 기반 접근 제어
  • 허용된 출처에서만 API 접근 가능

6. 중요 포인트

  • Spring Security가 인증 처리를 자동으로 수행
  • React는 세션 쿠키를 통해 인증 상태 유지
  • 모든 API 요청은 인증된 세션을 통해 처리
  • 권한에 따른 기능 접근 제어 가능
  • CORS 설정으로 허용된 클라이언트만 접근 가능

'스프링' 카테고리의 다른 글

스프링 - REST API  (0) 2024.12.17
스프링 시큐리티 - 간단한 인증절차 정리  (0) 2024.12.16
스프링 - 트랜잭션 이해 (2)  (0) 2024.12.13
스프링 파라미터 처리 과정  (0) 2024.12.12
스프링 - 스프링  (0) 2024.12.09

댓글