✅ 🔧 해결 방향 설정
formLogin()은 기본 로그인 페이지를 사용하는 방식
→ 우리가 사용하는 프론트엔드 커스텀 로그인과는 충돌
- 따라서
formLogin() 제거 후, 직접 로그인 API를 만들고 JWT 발급 방식으로 전환
✅ 🔐 SecurityConfig 수정 요약
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, CorsConfigurationSource corsConfigurationSource) throws Exception {
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/auth/login", "/api/auth/register").permitAll()
.anyRequest().authenticated()
)
.logout(logout -> logout
.logoutUrl("/api/auth/logout")
.logoutSuccessHandler((request, response, authentication) -> {
response.setStatus(HttpStatus.OK.value());
})
)
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider),
UsernamePasswordAuthenticationFilter.class);
return http.build();
}
✅ 👤 로그인 API 흐름 정리
🔹 1) @RestController 작성
@PostMapping("/login")
public ResponseEntity<LoginResponse> login(@RequestBody LoginRequest request) {
log.info("로그인 요청: Email={}", request.getEmail());
LoginResponse loginResponse = authService.login(request);
log.info("로그인 결과: {}", loginResponse);
return ResponseEntity.ok(loginResponse);
}
🔹 2) 로그인 로직 (authService.login())
- 이메일로 사용자 조회 → 비밀번호 확인 → JWT 발급 → 로그인 성공 여부 반환
@Transactional
public LoginResponse login(LoginRequest request) {
Optional<User> optionalUser = userRepository.findByEmail(request.getEmail());
if (optionalUser.isEmpty()) return 실패 응답;
User user = optionalUser.get();
if (!passwordEncoder.matches(request.getPassword(), user.getPassword()))
return 실패 응답;
String token = jwtTokenProvider.createToken(user.getEmail(), List.of(user.getRole().name()));
return 성공 응답;
}
✅ 🔎 프론트엔드 로그인 코드 확인
🔹 React 로그인 버튼 클릭 시 동작
const handleLogin = async() => {
try {
const response = await login({ email, password });
console.log(response);
} catch(err) {
console.log(`로그인 실패 : ${err}`);
alert("로그인 실패");
}
}
🔹 axios 요청 구조
export const login = async(data: LoginRequest): Promise<LoginResponse> => {
return (await axios.post('/auth/login', data)).data;
}
✅ 반드시 알아야 할 개념 요약
- 브라우저 기반 폼 로그인 페이지 자동 제공
- 우리가 사용하는 API 방식에는 맞지 않음
🔑 2. API 로그인 방식
- 클라이언트가 직접 로그인 API 호출 (
/api/auth/login)
- JWT를 응답으로 받아 클라이언트가
Authorization 헤더에 넣어 요청
🪪 3. JWT (JSON Web Token)
- 사용자의 인증 정보를 담은 서명된 토큰
- 프론트에서
Authorization: Bearer <token> 형태로 헤더에 추가
🛡️ 4. JwtAuthenticationFilter
- 클라이언트 요청이 들어올 때마다 JWT가 있는지 확인 → 인증 객체 생성