티스토리 뷰
마이그레이션이란 데이터베이스 스키마의 변경 내역을 버전 관리하여, 변경에 대한 이력을 남기고, 데이터베이스를 이전 버전에서 최신 버전으로 옮기는 일련에 과정들을 의미합니다.
즉, 일반적으로 마이그레이션은 스키마를 변경하거나 새로운 테이블이나 컬럼을 추가하는 등에 작업을 포함하고 따라서 우리가 할 작업 H2 데이터베이스에서 MySQL 로 변경할 때도 마이그레이션을 수행 한다고 할 수 있습니다. 이러한 이경우에 테이터 스키마를 변경하거나 데이터를 이전하는 작업등이 포함 될 수 있습니다.
1. SpringSecurityCrypto 의존성 추가 및 BCryptPasswordEncoder 빈 클래스로 등록
주의!
spring-security 에서 제공하는 crypto라는 라이브러리를 활용합니다.
이번 프로젝트에서는 Spring Security를 활용하지 않습니다.
Spring Security Crypto
org.springframework.security:spring-security-crypto 모듈은 스프링 시큐리티 프레임워크의 일부로, 암호화와 해싱을 위한 기능을 제공합니다.
이 모듈은 비밀번호 저장, 데이터 암호화 및 디지털 서명을 위한 API를 포함하며, 개발자가 보안 관련 작업을 보다 쉽게 구현할 수 있도록 돕습니다. 주로 사용되는 기능은 비밀번호 인코딩(해싱)과 텍스트 데이터의 암호화/복호화입니다.
의존성 추가 하기 - gradle 파일에 추가 후 새로 고침
// 암호화
implementation 'org.springframework.security:spring-security-crypto'
회원가입 후 DB 확인
WebMvcConfig - 코드 추가 (PasswordEncoder Bean 처리)
@Bean // IoC 대상(싱글톤 처리)
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
해당 메서드가 Spring 컨테이너에 의해 관리되는 Bean을 생성하고 반환합니다.
IoC(Inversion of Control) 대상
이 Bean의 생명주기와 관리를 개발자가 직접 하지 않고 Spring이 대신 관리한다는 의미입니다.
@Bean 어노테이션을 통해 메서드가 반환하는 객체(BCrytPasswordEncoder)가 Spring 컨테이너에 싱글톤으로 등록됩니다. 즉, 애플리케이션 전체에서 이 Bean은 하나만 생성되어 사용됩니다.
passwordEncoder는 Bean의 이름으로도 사용됩니다.
return new BCryptPasswordEncoder();
위의 코드는 BcrytPasswordEncoder 객체를 생성하여 반환하고, Spring Security에서 제공하는 클래스이며, 암호를 해싱하고 검증하는 기능을 수행합니다.
@Bean 어노테이션으로 인해 Spring 컨텍스트에 등록되며, 이후 다른 클래스에서@Aurowired 또는 생성자 주입을 통해 PasswordEncoder Bean의 의존성을 주입받아 사용할 수 있습니다.
즉, 이 코드는 Spring 애플리케이션 컨텍스트에 PasswordEncoder 타입의 Bean을 등록하는 역할을 합니다.
2. 회원가입 시 회원 비밀번호 암호화 처리
UserService 코드 수정
회원 가입 시 비밀번호 암호화 처리
/**
* 회원 등록 서비스 기능
* 트랜잭션 처리
* @param dto
*/
@Transactional // 트랜잭션 처리는 반드시 습관화
public void createUser(SignUpDTO dto) {
// 암호화
int result = 0;
try {
// 코드 추가 부분
// 회원 가입 요청 시 사용자가 던진 비밀번호 값을 암호화 처리 해야함
// DI : 존재하는 객체를 가져옴
String hashPwd = passwordEncoder.encode(dto.getPassword()); // 섞음
System.out.println("hashPwd:" + hashPwd);
dto.setPassword(hashPwd);
result = userRepository.insert(dto.toUser());
} catch (DataAccessException e) {
throw new DataDeliveryException("중복 이름을 사용할 수 없습니다.", HttpStatus.INTERNAL_SERVER_ERROR);
} catch (Exception e) {
throw new RedirectException("알 수 없는 오류", HttpStatus.SERVICE_UNAVAILABLE);
}
if(result != 1) {
throw new DataDeliveryException("회원가입 실패", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
3. 로그인 시 암호화된 비번 확인 및 기능 추가
UserRepository 코드 추가
public User findByUsername(@Param("username") String username);
user.xml 코드 추가
username으로 user 정보 조회
<select id="findByUsername" resultType="com.tenco.bank.repository.model.User" >
select * from user_tb where username = #{username}
</select>
UserService 코드 수정
로그인 시 userEntity(암호화되어 DB에 있는 값)와 dto.getPassword()(사용자가 입력한 값)가 동일하면 true 반환
public User readUser(SignInDTO dto) {
// 유효성 검사는 Controller 에서 먼저 하자.
User userEntity = null; // 지역 변수 선언
// 기능 수정
// username으로만 --> select
// 2가지의 경우의 수 -- 객체가 존재 or null
// 객체 안에 사용자의 password가 존재한다.(암호화 되어 있는 값)
// passwordEncoder 안에 matches 메서드를 사용해서 판별한다. 사용자("1234".equals(@@@!!!));
try {
userEntity = userRepository.findByUsername(dto.getUsername());
} catch (DataAccessException e) {
throw new DataDeliveryException("잘못된 처리 입니다.", HttpStatus.INTERNAL_SERVER_ERROR);
} catch (Exception e) {
throw new RedirectException("알수 없는 오류", HttpStatus.SERVICE_UNAVAILABLE);
}
if(userEntity == null) {
throw new DataDeliveryException("존재하지 않은 아이디입니다.", HttpStatus.BAD_REQUEST);
}
// 비밀번호가 맞는지 확인
// 사용자가 입력한 비밀번호와 쿼리문으로 걸러진 DB에 있는 비밀번호가 같으면 true를 반환한다.
boolean isPwdMatched = passwordEncoder.matches(dto.getPassword(), userEntity.getPassword());
if(isPwdMatched == false) {
throw new DataDeliveryException("비밀번호가 잘못되었습니다.", HttpStatus.BAD_REQUEST);
}
return userEntity;
}
인코딩해서 해싱(암호화)한 DB에 들어가있는 값과 사용자가 입력한 값도 인코딩 되어 비교된다.
'Spring boot' 카테고리의 다른 글
스프링 부트 핵심 콘셉트 (0) | 2024.09.27 |
---|---|
파일 업로드 - 1 단계(멀티파트) (0) | 2024.08.13 |
intercepter 활용(인증검사 공통 처리) + @configuration과 @Bean의 차이 (0) | 2024.08.13 |
계좌 상세보기 - 2단계(기능, 동적 쿼리 구현) + Format 처리 + 페이징 처리 (0) | 2024.08.12 |
계좌 상세보기 - 1단계(쿼리 학습) (0) | 2024.08.09 |