SpringSecurityCrypto 의존성 추가 및 BCryptPasswordEncoder 빈 등록
회원가입 시 비밀번호를 안전하게 암호화하여 저장
로그인 시 암호화된 비밀번호를 검증하는 기능 추가
전체 코드 확인 및 실행 흐름 이해
🚨 주의
- 비밀번호 암호화 후에는 기존 H2 데이터베이스에 저장된 유저로 로그인할 수 없습니다.
- 비밀번호 검증 방식이 변경되었으므로, 반드시 새로운 유저를 가입한 후 테스트하세요.
1. Spring Security 의존성 추가하기
먼저, Spring Security의 암호화 기능을 사용하기 위해 Gradle에 의존성을 추가해야 합니다.
Gradle 설정 (build.gradle)
// Spring Security 암호화 기능 추가
implementation 'org.springframework.security:spring-security-crypto'
- spring-security-crypto 라이브러리는 BCryptPasswordEncoder와 같은 암호화 기능을 제공합니다.
- Gradle에서 의존성을 추가한 후 새로 고침(Refresh)을 해주세요.
2. BCryptPasswordEncoder를 Spring Bean으로 등록하기
WebMvcConfig.java (설정 파일)
package com.tenco.bank.config;
import com.tenco.bank.handler.AuthInterceptor;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration // 스프링 설정 클래스
@RequiredArgsConstructor
public class WebMvcConfig implements WebMvcConfigurer {
// 인증 인터셉터 주입
private final AuthInterceptor authInterceptor;
// 인증이 필요한 URL 패턴 추가
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor)
.addPathPatterns("/account/**")
.addPathPatterns("/auth/**");
}
// 📌 BCryptPasswordEncoder를 Spring Bean으로 등록
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
- @Bean을 사용하여 BCryptPasswordEncoder를 스프링 빈으로 등록
- 이제 어디서든 DI(의존성 주입)를 통해 passwordEncoder를 사용할 수 있음
- BCryptPasswordEncoder는 비밀번호를 안전하게 해시화하고 검증하는 역할을 함
3. 회원가입 시 비밀번호 암호화 처리하기
회원가입 시 사용자가 입력한 비밀번호를 암호화한 후 데이터베이스에 저장해야 합니다.
UserService.java (회원 가입 기능)
package com.tenco.bank.service;
import com.tenco.bank.domain.User;
import com.tenco.bank.dto.SignUpDTO;
import com.tenco.bank.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
// 📌 회원가입 기능
@Transactional
public void createUser(SignUpDTO dto) {
int result = 0;
try {
// 1️⃣ 비밀번호 암호화
String hashPwd = passwordEncoder.encode(dto.getPassword());
dto.setPassword(hashPwd); // 암호화된 비밀번호 저장
// 2️⃣ 데이터베이스에 저장
result = userRepository.insert(dto.toUser());
} catch (Exception e) {
throw new RuntimeException("회원가입 중 오류 발생", e);
}
// 3️⃣ 데이터 저장 실패 시 예외 발생
if (result != 1) {
throw new RuntimeException("회원 가입 실패");
}
}
}
- 사용자의 입력 비밀번호를 passwordEncoder.encode()를 사용하여 암호화
- DB에 저장할 때는 해시된 비밀번호를 저장
- 트랜잭션을 적용하여 데이터 무결성을 보장
4. 로그인 시 암호화된 비밀번호 확인
이제 로그인할 때 입력한 비밀번호와 DB에 저장된 암호화된 비밀번호를 비교하는 로직을 추가해야 합니다.
UserService.java (로그인 기능)
public User readUser(SignInDTO dto) {
User user = null;
try {
// 1️⃣ 아이디로 사용자 조회
user = userRepository.findByUsername(dto.getUsername());
} catch (Exception e) {
throw new RuntimeException("로그인 처리 중 오류 발생", e);
}
// 2️⃣ 사용자 정보가 없을 경우 예외 발생
if(user == null) {
throw new RuntimeException("아이디 혹은 비밀번호가 틀렸습니다.");
}
// 3️⃣ 비밀번호 비교 (matches 메서드 사용)
boolean isPwdMatched = passwordEncoder.matches(dto.getPassword(), user.getPassword());
if(!isPwdMatched) {
throw new RuntimeException("비밀번호가 잘못되었습니다.");
}
return user;
}
- 사용자가 입력한 비밀번호와 DB에 저장된 해시된 비밀번호를 passwordEncoder.matches()로 비교
- 비밀번호가 일치하지 않으면 로그인 실패 처리
- 평문 비밀번호를 직접 비교하는 것이 아니라, BCrypt의 해시값을 검증하는 것이 중요!
5. 최종 코드 정리
✅ BCryptPasswordEncoder를 활용한 전체 과정 요약
- Spring Security Crypto 의존성 추가 (build.gradle)
- BCryptPasswordEncoder를 Bean으로 등록 (WebMvcConfig.java)
- 회원가입 시 비밀번호 암호화 후 저장 (UserService.java)
- 로그인 시 암호화된 비밀번호와 비교하여 검증 (UserService.java)
기존 평문 비밀번호 저장 방식은 보안상 위험
BCryptPasswordEncoder를 사용하면 비밀번호를 안전하게 암호화할 수 있음
로그인 시 입력된 비밀번호를 DB의 해시된 값과 비교하여 검증