예외처리에서 중요하다고 생각하는 부분은 기존의 사용자가 설정한 비밀번호를 암호화 하는 것이라고 생각한다.
일단 전혀 지식이 없기에 구글링을 먼저 해보았다.
Spring Boot에 암호화 하는 방법은 꽤나 있었고, 그 중 요구사항에 따라 먼저 직접 적용시켜보기로 했다.
다만 처음보는 코드이기에 해석을 먼저 해보기로 했다.
import at.favre.lib.crypto.bcrypt.BCrypt; // BCrypt 라이브러리를 불러와서 비밀번호 암호화 기능을 사용
import org.springframework.stereotype.Component; // 스프링이 이 클래스를 빈으로 관리할 수 있게 해주는 어노테이션
@Component // 스프링 컨테이너가 이 클래스를 자동으로 빈 등록하도록 설정
public class PasswordEncoder {
public String encode(String rawPassword) { // 사용자가 입력한 평문 비밀번호를 암호화하는 메서드
return BCrypt.withDefaults() // 기본 설정을 사용하여 BCrypt 객체 생성
.hashToString(BCrypt.MIN_COST, rawPassword.toCharArray());
// MIN_COST는 암호화 강도 중 가장 빠른 옵션을 사용
// rawPassword를 char 배열로 바꿔 bcrypt로 해시한 후 문자열 형태로 반환
}
public boolean matches(String rawPassword, String encodedPassword) {
// rawPassword: 사용자가 로그인 시 입력한 평문 비밀번호
// encodedPassword: DB에 저장된 암호화된 비밀번호
BCrypt.Result result = BCrypt.verifyer()
.verify(rawPassword.toCharArray(), encodedPassword);
// rawPassword를 char 배열로 변환
// encodedPassword와 일치하는지 bcrypt 알고리즘으로 비교
return result.verified; // 검증 결과(true/false)를 반환
}
}
1) 절대 원래 비밀번호로 되돌릴 수 없음
2) Salt 자동 적용
3) 강도(cost factor)를 조절할 수 있음
비밀번호 저장용으로 특화된 해시 알고리즘
salt 자동 포함
매번 결과가 달라서 안전
cost로 보안 강도 조절 가능
복호화 불가능(단방향)
따라서 비밀번호 생성 시 암호화된 비밀번호를 저장하고, 특정 비밀번호를 요구하는 API를 실행할 때 사용자가 생성할 때 쓴 비밀번호의 암호화 코드와, 요구한 비밀번호의 암호화 코드가 일치하면 실행이 되게끔 작동된다는 것이다.
회원가입 시 인코드를 통해 암호화를 적용을 시키고, 요구하는 해당 서비스의 조건문을 암호화 비교로 바꾼다.
User user = new User(request.getUserName(), request.getEmail(), request.getPassword());
if (!user.getPassword().equals(request.getPassword())) {
throw new IllegalArgumentException("비밀번호가 올바르지 않습니다.");
}
User user = new User(request.getUserName(), request.getEmail(), request.getPassword());
if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
throw new IllegalArgumentException("비밀번호가 올바르지 않습니다.");
}
잘 작동한다.
Comment 엔티티 만들기
Repository 만들기
DTO 만들기
Service 로직 작성
Controller 만들기
권한 검증(service) 추가
Validation 적용
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "schedule_id")
private Schedule schedule;
List<Comment> findAllByScheduleId(Long scheduleId);
private final CommentRepository commentRepository;
private final ScheduleRepository scheduleRepository;
private final UserRepository userRepository;
--------------------------------------------
saved.getId(),
saved.getUser().getUserName(),
public ResponseEntity<Void> delete(
@SessionAttribute(name = "loginUser", required = false) SessionUser sessionUser,
@PathVariable Long commentId)
-------------------------------------------------
commentService.delete(commentId, sessionUser.getId());
작성간 유의사항으로는 모두 만들고나서 오류가 났었는데 그 이유는 레퍼지토리에 들어가있는 메서드의 형식이 어긋나 있었다.
List<Comment> findAllbyScheduleId(Long scheduleId);
위와 같이 중간에 대문자 B가 아닌 b가 들어가 작동하지 않는 현상을 보았고, 카멜형식을 제대로 지켜야겠다는 생각이 들었다..