1. 문제
스프링 시큐리티를 사용해서 비밀번호를 저장하면 암호화 되어 아래와 같이 Hash 로직에 의해 암호화 되서 들어간다.
저장은 했는데, 입력했을 때 비교는 어떻게 할까?
// 비밀번호 검증
public boolean authPassword(String email, String password) {
// 이메일로 유저 검증
Optional<User> optionalUser = userRepository.findByEmail(email);
if (optionalUser.isPresent()) {
// 유저가 있다면 existsByPassword로 비교
User user = optionalUser.get();
String passwordHash = bCryptPasswordEncoder.encode(password);
boolean exist = userRepository.existsByPassword(passwordHash);
if (exist) return true;
else return false;
}
return false;
}
처음 서비스 로직을 작성할 때 단순히 데이터베이스에서 바로 비교하거나 equals로 확인하면 안된다. 그 이유는 BCryptPasswordEncoder는 암호화를 수행할 때마다 랜덤 솔트를 추가해서 같은 비밀 번호도 매번 다른 해시값을 생성한다.
여기서 솔트 데이터는 비밀번호를 처리하는 단방향 함수의 추가 입력으로 사용되는 랜덤 데이터라고 한다.
출처 : 솔트(암호학) - 위키백과
BCrypt는 복호화가 불가능한 방식으로 위에서 단방향이라는 말이 암호화된 비밀번호를 반대로는 되돌릴 수 없다는 말이다.
2. 문제 해결
public boolean authPassword(String email, String inputPassword) {
Optional<User> optionalUser = userRepository.findByEmail(email);
if (optionalUser.isPresent()) {
User user = optionalUser.get();
// matches를 사용하여 입력 비밀번호와 저장된 해시값을 비교
return bCryptPasswordEncoder.matches(inputPassword, user.getPassword());
}
return false; // 사용자 정보가 없으면 false 반환
inputPassword는 내가 확인하려고 넣은 비밀번호이고, user.getPassword( )는 DB에 들어 있는 비밀번호이다. BCryptPasswordEncoder에서 제공하는 matches 함수를 이용하면 위와 같이 간단하게 비교할 수 있다.
[결론] : 프로젝트 때문에 바빠서 글 못올렸는데 올릴게 산더미⛰️⛰️⛰️