today_is
[ spring ] HashComponent 이용하기 본문
오늘의 목표
HashComponent 를 이용하여, 비밀번호에 해시함수를 적용시켜보자
HashComponent
: userpw 를 sha-512 해시 알고리즘이 적용된 상태로 바꿔주기 위한 컴포넌트 (보안을 위해서)
@Component
: Controller, Service, Repository 에 해당하지 않지만, 특정 내용에 대한 코드를 수행하기 위해 작동하는 스프링 빈
package com.itbank.component;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.springframework.stereotype.Component;
@Component
public class HashComponent {
// 문자열 input을 전달받아서 sha-512 해시 알고리즘이 적용된 output을 반환하는 함수
// 입력값이 같으면 출력값도 같다
// 비밀번호 일치여부를 확인할 수 있다
// DB에는 해시처리된 값이 저장되므로, DB 관리자도 패스워드를 확인할 수 없다
public String getHash(String input) {
MessageDigest md;
String output = null;
try {
md = MessageDigest.getInstance("SHA-512");
md.update(input.getBytes());
output = String.format("%0128x", new BigInteger(1, md.digest()));
} catch(NoSuchAlgorithmException e) {
e.printStackTrace();
}
return output;
}
}
MemberService
: userpw 에 HashComponent 적용
HashComponent 객체 생성
: @Autowired 를 이용하여, hashComponent 와 연결할 객체를 생성해야한다
hashComponent를 적용해야할 곳
1) 회원가입할 때 (add 함수)
: 사용자가 입력한 userpw를 hash형태로 저장해둠
코드해석
사용자가 입력한 회원가입 정보를 MemberDTO 형태로 받아온다
-> public int add(MemberDTO dto) {
입력한 비밀번호를 getUserpw로 가져와서 hash 처리를 하고 변수에 저장해둔다
-> String hash = hashComponent.getHash(dto.getUserpw());
hash 변수를 setUserpw 를 이용하여 userpw 에 담는다
-> dto.setUserpw(hash);
dto를 MemberDAO에 있는 insert()함수를 이용하여 새로운 데이터를 생성한다 (== 회원가입)
-> return dao.insert(dto);
2) 로그인할 때 (login 함수)
: 애초에 hash형태로 비번을 저장했기 때문에,
로그인시에도 hash형태의 입력값과 userpw 를 비교한 뒤에
아이디와 비밀번호가 일치하면 로그인이 되도록 해야한다
코드 해석
사용자가 입력한 패스워드로 해시값을 생성한다
-> String hash = hashComponent.getHash(dto.getUserpw());
만들어진 해시값을 이용하여 DB에 저장된 해시값과 비교한다
-> dto.setUserpw(hash);
return dao.login(dto);
package com.itbank.service;
import java.util.List;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.itbank.component.HashComponent;
import com.itbank.model.MemberDTO;
import com.itbank.repository.MemberDAO;
@Service
public class MemberService {
@Autowired private MemberDAO dao;
@Autowired private HashComponent hashComponent;
public List<MemberDTO> getMemberList() {
List<MemberDTO> list = dao.selectList();
list.forEach(dto -> dto.setUserpw("********"));
return list;
}
public MemberDTO getMember(int idx) {
return dao.selectOne(idx);
}
public int add(MemberDTO dto) {
String hash = hashComponent.getHash(dto.getUserpw());
dto.setUserpw(hash);
return dao.insert(dto);
}
public MemberDTO login(MemberDTO dto) {
String hash = hashComponent.getHash(dto.getUserpw());
dto.setUserpw(hash);
return dao.login(dto);
}
public int delete(int idx) {
return dao.delete(idx);
}
public int modify(MemberDTO dto) {
String hash = hashComponent.getHash(dto.getUserpw());
dto.setUserpw(hash);
int row = dao.update(dto);
return row;
}
public String resetPass(MemberDTO dto) {
String newPassword = UUID.randomUUID().toString().replace("-", "").substring(0, 8);
String hash = hashComponent.getHash(newPassword);
System.out.println("newPassword : " + newPassword);
System.out.println("hash : " + hash);
dto.setUserpw(hash);
int row = dao.updatePassword(dto);
return row != 0 ? newPassword : null;
}
}
study_reivew
계속 로그인에 실패해서 원인을 알수 없었는데
DB 를 통해 Userpw 값이 어떻게 저장되어있는지를 보고 나서야 문제점을 알게되었다.
회원가입할때는 hash형태로 저장했는데
로그인할때에는 입력값을 hash 형태로 바꾸지 않은채로 비교를 했기 때문에 로그인에 실패했었던 것이다..
항상 문제가 있을때에는 어떤 구조로 왜 이런 결과가 나왔는지를 먼저 생각해보는 것이 가장 중요한 것 같다
'spring' 카테고리의 다른 글
[ spring ] 어노테이션 문법정리 (0) | 2024.01.02 |
---|---|
[ spring ] Interceptor (0) | 2024.01.01 |
[ spring ] mybatis mapper 이용 (0) | 2023.12.28 |
[ spring ] 스프링과의 첫만남 (0) | 2023.12.27 |
[ spring ] 스프링 구조파악 (0) | 2023.12.26 |