본문 바로가기
Framekwork/photogram

[스프링 부트 포토그램] 20강 인증 회원가입 - 비밀번호 해시 (BCryptPasswordEncoder)

by 아이엠제니 2024. 9. 3.

IDE: IntetlliJ Ultimate
Spring Boot: 3.3.0
JDK: 17


 

 

 

💾 SecurityConfig.java

@Configuration // IoC
@EnableWebSecurity // 해당 파일로 시큐리티 활성화
public class SecurityConfig {

    @Bean
    public BCryptPasswordEncoder encode() {
        return new BCryptPasswordEncoder();
    }
.
.
.
}

`SecurityConfig`에 `BCrytPasswordEncoder` 추가

 

> BCryptPasswordEncoder

  • Spring Security에서 제공하는 암호화(비밀번호 해시) 클래스 중 하나
  • 비밀번호를 안전하게 저장하기 위해 사용됨
  • `BCrypt` 해시 함수에 기반하며, 비밀번호를 해시하고 그 해시 값을 저장하거나, 저장된 해시 값을 기반으로 비밀번호의 유효성을 검사할 때 사용됨
  • 특징
    • 강력한 보안
      • `Bcrypt` 알고리즘은 해시와 솔트(salt) 기법을 사용하여 비밀번호를 안전하게 보호함
      • 솔트는 해시 전에 무작위 값이 비밀번호에 추가되어 같은 비밀번호도 매번 다른 해시값으로 저장되도록 함
    • 해시 속도 조절
      • `Bcrypt`는 작업량을 조절할 수 있는 비용 인자를 제공함
      • 이를 통해 비밀번호 해시 계산 속도를 조정할 수 있어 보안 요구사항에 따라 성능과 안전성의 균형을 맞출 수 있음
    • 안전한 비밀번호 비교
      • `BcryptPasswordEncoder`는 해시된 비밀번호와 사용자가 입력한 비밀번호를 안전하게 비교하는 메서드를 제공함
      • 타이밍 공격을 방지하는 방식으로 구현되어 있음

 

 

 

💾 AuthService.java

@RequiredArgsConstructor
@Service // 1. IoC, 2. 트랜잭션 관리
public class AuthService {

    private final UserRepository userRepository;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    @Transactional // Write(insert, Update, Delete)
    public User join(SignupReqDto signupReqDto) {

        String rawPassword = signupReqDto.getPassword();
        String encPssword = bCryptPasswordEncoder.encode(rawPassword);
        signupReqDto.setPassword(encPssword);
        signupReqDto.setRole("ROLE_USER"); // 관리자 ROLE_ADMIN

        return userRepository.save(signupReqDto.toEntity());
    }

}

 

`SecurityConfig`에서 추가한 ` BCrytPasswordEncoder` 의존성 추가

`join` 메서드에 `@Transactional` 애너테이션 추가

`siupReqDto` 파라미터로 들어오는 password를 암호화 해줌

그리고 유저 권한 추가

기존에 `role`은 `SignupReqDto`에 필드가 없어서, 새로 추가해줌

 

 

 

💾 SignupReqDto.java

@Data // Getter, Setter
public class SignupReqDto {
    private String username;
    private String password;
    private String email;
    private String name;
    private String role;

    public User toEntity() {
        return User.builder()
                .username(username)
                .password(password)
                .email(email)
                .name(name)
                .role(role)
                .build();
    }
}

`role` 필드 추가하고, `toEntity()` 메서드의 빌드 패턴에도 `role` 추가

 

 

여기까지 완료하고 회원가입을 해보면?

동일 유저 정보를 가입을 했을 때, db에 여러번 쌓이고 있는 것을 확인할 수 있다.

 

 

 

💾 User.java

@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Data
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 번호 증가 전략이 DB를 따라감
    private Long id;

    @Column(unique = true)
    private String username;
.
.
.
}

`User` entity에서 `usrname` 필드에 `unique=true` 옵션을 준다

 

 

 

그리고 동일 `username`으로 가입을 시도하려고 하면, 위와 같이 [Whitelabel Error Page] 를 보게 된다.

사용자 화면에 위와 같이 보이면 안 되기 때문에, 처리가 필요하다.

그건 다음 강으로.

 

 

 

이지업클래스 [메타코딩] 스프링부트 SNS프로젝트 - 포토그램 만들기 강의 실습

참고
OpenAi. (2024) ChatGPT (version 3.5)[Large Language model]. https://chat.openai.com

 

 

 

300x250