(부제 : 비밀번호가 계속 바뀜)
비밀번호 초기화를 위한 인증 메일을 보내면, 비밀번호가 임의의 값으로 바뀌어버린다. (?) 원래는 잘됐었는데,,,,,,,
최근에는 DB에서 UserId를 암호화하여 저장하게 됐는데, 이때까지만 해도 Attribute Converter
를 목적에 맞게 잘 사용하고 있었다. 그러나, Password까지 Attribute Converter를 사용하게 된 것이 문제의 화근이었다. (기존에는 Password는 회원가입/비밀번호 재설정 할때마다 따로 암호화하여 저장해서 사용하고 있었다.)
Spring Security 에 대한 간략한 정보는 (이곳을 클릭)하여 알 수 있다.
PasswordEncoder 에 대한 간략한 정보는 (이곳을 클릭)하여 알 수 있다.
Attribute Converter 에 대한 간략한 정보는 (이곳을 클릭)하여 알 수 있다.
이 방식은 실무에서 쓰이는 방식은 아니고, 신입 프로젝트에서 진행한 서비스의 동작 방식이다.
빨간색으로 색칠된 부분에서 비밀번호가 재설정되었다.
0. 배경
에서도 소개했다 시피, 유저가 비밀번호 초기화를 시도만 해도 비밀번호가 임의의 값으로 바뀌는 현상이다. 자세한 설명을 위해 아래 코드와 사진을 함께 첨부한다.
package 패키지명
import 패키지명.PasswordConverter
import javax.persistence.*
@Entity
@Table(name = "USER")
// 회원관리 테이블
data class UserEntity(
// 다른 속성들 더 있음...
@Column(name = "user_password", length = 100)
@Convert(converter = PasswordConverter::class)
var userPassword: String = "",
@Column(name = "user_token", length = 30)
// 비밀번호 재설정 할때 사용할 토큰
var userToken: String? = null
) : BaseTimeEntity()
우선 기본적인 UserEntity
의 구성은 위와 같다. Password에 Converter가 적용되어 있는 모습.
// 사용자에게 새로운 토큰 발급
@Throws(UsernameNotFoundException::class)
@Transactional
override fun updateToken(token: String, email: String) {
val entity = repository.findByUserEmail(email)
?: throw UsernameNotFoundException("invalid email.")
entity.userToken = token
}
위 코드는 패스워드 초기화를 위한 Token을 할당하는 부분이다.
service.updateToken()
이 실행되기 전 모습이다.
user_password
와user_token
을 먼저 확인하자.
아래 사진은 updateToken()
이 실행된 후의 모습이다.
user_password
와user_token
이 변경된 것을 볼 수 있다.
위에 코드에서 봤듯, updateToken()
에서는 Password를 수정하는 부분이 없는데.
문제의 원인은 AttributeConverter
와 SpringSecurity
에 모두 있었다.
AttributeConverter
는 @Converter 어노테이션을 붙이지 않은 데이터'만' 수정할 때에도 동작한다.BCryptPasswordEncoder
는 매번 다른 비밀번호가 생성된다.
(동일한 비밀번호를 암호화 하더라도, 매번 다른 비밀번호가 만들어진다.)
이 두개가 맞물려 동작하면서, UserEntity
에서 다른 정보를 수정할 때 Password가 변경되던 것이다.
UserEntity
에서 Password에 @Converter를 제거했다.