아래의 두 포스트와 연결되는 내용
지난 포스트에선 일반 문자열로 저장된 비밀번호를 @ElementCollection 어노테이션을 통해 별도의 테이블에 맵핑을 하였고, user.passwordList 로 호출할 수 있도록 하였다.
이제 SpringSecurity 를 적용하고 나서 비밀번호를 passwordEncoder 를 통해 저장하고, 이를 호출하여 비밀번호 체크를 하도록 설정하였다.
var pw = passwordEncoder.encode(request.password)
...
password = pw,
passwordList = mutableListOf(pw),
그리고 새 비밀번호를 passwordEncode.encode(newPassword) 로 변환하여 passwordList 안에 포함되어 있는지 in 으로 지난 알고리즘대로 실행을 하였는데 도통 안되는 것이라..
정확히는 이미 List에 저장되어있는 비밀번호를 입력해도 리스트 내부에서 포함됨을 인지하지 못하고 아무 저항 없이 반영해주는 것이었다.
newPassword 값이 잘못됐나? 공백이나 데이터형이나 뭔가 잘못 처리가 되고 있나? 정확히 입력하였는데.. 같은 값을 encode 하면 같은 결과가 나와야 하는것 아닌가? -> 아니었다.
결론부터 말하자면 이미 인코딩 된 비밀번호와 비교를 할 땐 반드시 .matches() 메서드를 사용해야 한다.
왜냐하면 .encode() 메서드에선 "안전한 해싱" 알고리즘을 사용하여 같은 값이라도 결과값은 매번 달라질 수 있고, 결과물 간의 비교를 할 수 없도록 하였기 때문이다. ( Salting 특성 : Salt라는 무작위 값을 추가하여 매번 결과가 달라지게 함 )
따라서 비밀번호는 encode 하기 전인 newPassword 값을 사용해 비교해야 하고 아래와 같이 표현할 수 있다.
passwordList 값을 하나씩 불러와 matches() 메서드로 비교하는 방법.
for (i in user.passwordList) {
if (passwordEncoder.matches(requestPw, i))
throw IllegalArgumentException("password already used")
}