Series/내가 해본

Spring Security 로 회원 가입을 구현해보자 (1)

Hyunec 2021. 6. 19. 01:26

생각해보니 저는 이미 구현되어 있는 인증을 가져다 쓰기만 할 뿐, 그 내부 구조는 이해하지 못하고 개발해온 것 같습니다.
그래서 이번 사이드 프로젝트에는 Spring Security 를 활용해 암호화부터 JWT 까지의 회원 가입을 구현했고 그 기록을 남겨봅니다.

아쉽게도 Spring Security 는 이해가 깊지 못해 일부 저의 방식으로 구현한 내용이 있습니다. 내용을 읽는데 참고해주세요.

코드는 일부 각색되었습니다.
각 Step 별 자세한 코드는 repository 의 서브 branch 를 참고해주세요.

Spring Security 로 회원 가입을 구현해보자

Step 1. 회원 가입

@Entity
public class Member {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  private String email;
  private String password;
}

최소한의 정보를 가진 회원 entity 를 만들고 정상 가입 됬지만,
비밀번호는 평문 그대로 저장되어 있습니다.

Step 2. 비밀번호 암호화

비밀번호 암호화를 위해 spring security 에서 제공하는 BCrypt 암호화를 사용합니다.

1. Security 설정

dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-security'
}


@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  ... security 기본 설정
}

build.gradle dependencies 와 WebSecurityConfig 를 추가합니다.

@Configuration
public class PasswordConfiguration {

  @Bean
  public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
  }
}

BCrypt 로 PasswordEncoder bean 을 생성합니다.

2. 비밀번호 암호화 적용

@RequiredArgsConstructor
@Converter
public class PasswordEncryptConverter implements AttributeConverter<String, String> {

  private final PasswordEncoder passwordEncoder;

  @Override
  public String convertToDatabaseColumn(String entityAttribute) {
    return passwordEncoder.encode(entityAttribute);
  }

  @Override
  public String convertToEntityAttribute(String databaseColumn) {
    // DB 에서 가져올 때는 복호화하지 않습니다.
    return databaseColumn;
  }
}


@Entity
public class Member {

  @Convert(converter = PasswordEncryptConverter.class)
  private String password;
}

Member entity 의 password 에 PasswordEncryptConverter 를 적용합니다.

3. 암호화 적용 테스트

@DisplayName("[성공] 회원 가입")
@Test
public void success_create() throws Exception {
  // given
  String password = "1q2w3e4r*";

  // when
  ... create

  // then
  assertThat(passwordEncoder.matches(password, member.getPassword())).isTrue();
}

JWT 적용은 다음 글로 이어집니다.