DB에 비밀번호를 그대로 저장하면 곤란하니까
비밀번호를 암호화해서 저장하고
로그인할 땐 복호화할 수 있도록 기능을 추가해보자!
BCryptPasswordEncoder 클래스를 이용했다!
일단 회원가입!
1) 객체를 받은 후
2) 비밀번호만 따로 인코딩해서 다시 객체에 넣어준다
3) 그 정보를 DB에 넣는다
Controller
@Autowired
BCryptPasswordEncoder passwordEncoder;
@PostMapping("/signUp") // /hi/signUp
@ResponseBody
public String signUpTest(@RequestBody MemberDto dto) throws Exception {
//받은 객체의 pwd를 인코더로 변환 후, 수정한다
String pwd = pwdEncode(dto.getPwd());
dto.setPwd(pwd);
//sql문으로 insert
int num = service.signUp(dto);
// insert가 동작했는지 알아보기 위해 출력
System.out.println("num = " + num);
String result = "";
if(num==1) {
result = "SignUp OK";
return result;
}
result="SignUp ERR";
return result;
}
비밀번호 암호화 메서드
public String pwdEncode (String pwd) {
String password = passwordEncoder.encode(pwd);
System.out.println("password = " + password);
return password;
}
매핑 SQL문
ㄴ 특수문자를 포함하니까, CDATA로 감싸주었다(특수문자 포함 가능하게 하는 MyBatis 기능)
ㄴ 이거 안 해도 되는 거 같다...ㅎㅎ 그냥 && 이나 이런 거 쓸 때 넣는 거인듯
<insert id="insert" parameterType="MemberDto">
<![CDATA[INSERT INTO member_info
(id, pwd, name, email, birth, reg_date)
VALUES
(#{id}, #{pwd}, #{name}, #{email}, now(), now())]]>
</insert>
하지만 이렇게 요리조리 수정을 해봐도
암호화된 패스워드는 들어가지 않는데
임의로 작성한 패스워드는 DB에 잘 저장되는 사태가 나타났다ㅠㅠ
에러코드)
info : org.springframework.beans.factory.xml.xmlbeandefinitionreader - loading xml bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
sql문에서 뭔가 문제가 있는 것으로 보여서
mapper에 있는 sql문을 직접 MySQL에 입력하고
내가 암호화했던 비밀번호를 복붙했더니 역시 삽입이 안 되는 것이다ㅠㅠ
그런데, 보다보니 암호화된 비밀번호가 너무 길었다...
생각해보니 pwd의 varchar(50) 밖에 안 된다는 걸 깨달았고
pwd의 varchar 용량(?)을 늘려주자 잘 작동하는 것을 확인했다 ^0^/
그러면 이제 복호화 도전!!!
LoginController
@ResponseBody
@PostMapping("/login")
public String login(@RequestBody MemberDto dto, HttpServletRequest request) {
// dto 잘 들어왔는지 확인
System.out.println("dto = " + dto);
// dto 널체크
if(dto!=null) {
try{
MemberDto memberDto = service.login(dto);
System.out.println("memberDtoPwd = " + memberDto.getPwd());
// memberDto 널체크
if(memberDto!=null) {
String id1 = dto.getId();
String id2 = memberDto.getId();
System.out.println("BEFORE matches");
boolean a = passwordEncoder.matches(dto.getPwd(), memberDto.getPwd());
System.out.println("a = " + a);
// 두 객체의 id, pwd 값이 같다면 로그인 성공
if(id1.equals(id2) && passwordEncoder.matches(dto.getPwd(), memberDto.getPwd())) {
HttpSession session = request.getSession();
session.setAttribute("id", id1);
return "LOGIN OK";
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
return "ID OR PWD CHECK PLZ";
}
분명히 비밀번호를 제대로 쳤는데도
passwordEncoder.matches() 가 nullpointerException이 뜬다
왜일까...?
일단 login SQL문은 특수문자를 사용할 수 있게 수정했고...
이유를 알았다!
1) 입력받은 dto의 id를 이용해서 유저 정보를 select 한 다음
2) DB에 들어가있는 pwd와 입력한 pwd를 비교해야하는데
자꾸 입력한 id와 pwd로 DB에 정보를 불러내려고 하니 안됐던 것 ㅠ.ㅠ
입력한 pwd와 맞는 DB 정보는 없기 때문이다 ㅠㅠ(암호화 전 pwd기 때문)
그럼 컨트롤러를 수정하자!
LoginController
@ResponseBody
@PostMapping("/login")
public String login(@RequestBody MemberDto dto, HttpServletRequest request) {
// dto 잘 들어왔는지 확인
System.out.println("dto = " + dto);
// dto 널체크
if(dto!=null) {
try{
//id로 form을 가져옴
MemberDto memberDto = service.form(dto.getId());
// memberDto 널체크
if(memberDto!=null) {
// 두 객체의 pwd 값이 같다면 로그인 성공
if(passwordEncoder.matches(dto.getPwd(), memberDto.getPwd())) {
HttpSession session = request.getSession();
session.setAttribute("id", dto.getId());
return "LOGIN OK";
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
return "ID OR PWD CHECK PLZ";
}
결과는?
DB에 암호화 된 pwd
하지만 유저가 회원 가입할 때 만든 pwd를 입력하면?
무사히 로그인 완료 :)
다음엔 무슨 기능을 구현해볼까?룰루랄라
'혼자서 개발새발' 카테고리의 다른 글
Spring) 게시판 페이지와 읽기 기능을 만들어보자! (0) | 2022.11.22 |
---|---|
Spring) 게시판 만들기 첫 단추 - DB Table, DTO, DAO, Mapper 만들기 (0) | 2022.11.18 |
Spring) 로그인 기능을 구현해보자! (0) | 2022.11.16 |
Spring) 아이디 중복 확인 기능을 구현해보자! (0) | 2022.11.16 |
Spring) 3편:ajax와 button으로 회원 가입 기능을 완성하다!! (0) | 2022.11.15 |