웹쟁이의 일상

[Spring] 회원가입 구현 - 5 <비밀번호 암호화> 본문

JAVA

[Spring] 회원가입 구현 - 5 <비밀번호 암호화>

jellyChoi 2019. 5. 23. 21:28

안녕하세요~ 벌써 회원가입을 위한 포스팅이 5개가 되었습니다!

 

저번 포스팅에서는 주소 검색을 위한 다음 주소 API를 사용하는 방법에 대해 알아보았습니다.

 

이번 포스팅은 비밀번호 암호화를 하고 회원가입을 마무리짓도록 하겠습니다.

 

$("#create").click(function(){
		var validate = ValidationCheck();
		if(validate == false) return false;
		if(confirm("회원가입을 하시겠습니까?") == true){
			loadingBarStart();
			if(doubleSubmitCheck()){
				return false;
			}
			$.ajax({
				type:"get",
				url : "<c:url value='/login/createIdAndEmailCheck.do'/>",
				/* encodeURIComponent
				예를들어, http://a.com?name=egoing&job=programmer 에서 &job=programmer 중 '&'는 하나의 파라미터가 끝나고 다음 파라미터가 온다는 의미이다.
				그런데 다음과 같이 job의 값에 &가 포함된다면 시스템은 job의 값을 제대로 인식할수 없게 된다. */
				data: "userId="+encodeURIComponent($('#userId').val())+"&userEmail="+encodeURIComponent($('#userEmail').val()),
				//data: {userId : $('#userId').val(), userEmail : $('#userEmail').val()},
				success:function(data) {
					if(data) {
						if(validate == true){
							var obj = document.frm;
							obj.action = "<c:url value='/login/userCreateSuccess.do'/>";
							obj.submit();
							lodingBarEnd();
						}
					}
					else{
						lodingBarEnd();
						alert("중복된 ID 또는 Email이 있습니다.");
					}
				},
				error: function(data){
					lodingBarEnd();
					alert('에러가 발생하였습니다.');
					return;
				}
			});
		}else{
			return false;
		}
	})

일단 스크립트를 작성해줍니다.

 

	@RequestMapping(value="/createIdAndEmailCheck.do", method=RequestMethod.GET)
	@ResponseBody
	public boolean createIdAndEmailCheck(@ModelAttribute UserVo userVo){
		String userId = userVo.getUserId();
		String userEmail = userVo.getUserEmail();
		int idCheckCnt = userService.createIdCheck(userId);
		int emailCheckCnt = userService.createEmailCheck(userEmail);
		if(idCheckCnt <= 0 && emailCheckCnt <= 0) return true;
		else return false;
	}

마지막으로 다시한번 아이디와 이메일 중복 체크를 해주겠습니다.

@RequestMapping(value="/userCreateSuccess.do", method=RequestMethod.POST)
	public String userCreateSuccess(@ModelAttribute @Valid UserVo userVo, BindingResult result, HttpServletResponse response, Model model, HttpSession session) throws Exception {
		// 유효성 검사에서 해당이 있을경우 아래 @valid에 걸려서 view로 리턴후 화면에 메세지 프로퍼티에 설정한 값으로 출력해준다
		if (result.hasErrors()) {//에러 찍어보기
			System.out.println("에러" + result.hasErrors());
			return "/login/userCreate";
		}

		String hashPassword = BCrypt.hashpw(userVo.getUserPw(), BCrypt.gensalt());
		userVo.setUserPw(hashPassword);      // 암호화 저장

		try{
			response.setContentType("text/html; charset=UTF-8");
			PrintWriter out = response.getWriter();
			userService.userCreateSuccess(userVo);
			out.println("<script>alert('정상적으로 회원가입이되었습니다.\\n로그인 페이지로 이동합니다.'); location.href='/login/login.do'</script>");
			out.flush();   // 현재 출력 버퍼에 저장되어 있는 내용을 웹 브라우저에 전송하고 비운다.
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}

아이디와 이메일 중복체크가 완료되면 데이터베이스에 유저 정보를 집어넣습니다.

 

그 전에 저번 포스팅에서도 언급했다시피, 비밀번호가 데이터베이스에 노출이 되는 일은 절대로 없어야합니다.

 

암호화 방법에는 여러가지가 있지만 오늘은 간단하게 BCrypt를 이용해서 비밀번호를 암호화 해보겠습니다.

 

<dependency>
	<groupId>org.mindrot</groupId>
	<artifactId>jbcrypt</artifactId>
	<version>0.4</version>
</dependency>

pom.xml에 위의 dependency를 추가해주세요.

String hashPassword = BCrypt.hashpw(userVo.getUserPw(), BCrypt.gensalt());
userVo.setUserPw(hashPassword);      // 암호화 저장

이 코드가 암호화를 하기 위한 코드입니다. BCrypt부분을 컨트롤 + 클릭 하시면 BCrypt.class를 확인하실 수 있습니다.

 

public interface UserService {
	public int createIdCheck(String userId);
	public int createEmailCheck(String userEmail);
	public void userCreateSuccess(UserVo userVo) throws Exception;
}
package com.co.kr.login.service.impl;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.co.kr.login.dao.UserDao;
import com.co.kr.login.service.UserService;
import com.co.kr.login.vo.UserAuthVo;
import com.co.kr.login.vo.UserVo;

@Service
public class UserServiceImpl implements UserService{
	
	@Autowired
	private UserDao userDao;

	@Override
	public int createIdCheck(String userId) {
		return userDao.createIdCheck(userId);
	}

	@Override
	public int createEmailCheck(String userEmail) {
		return userDao.createEmailCheck(userEmail);
	}

	@Override
	public void userCreateSuccess(UserVo userVo) throws Exception{
		userDao.userCreateSuccess(userVo);
	}


}

Service와 ServiceImpl을 완성해줍니다.

 

package com.co.kr.login.dao;

import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Repository;

import com.co.kr.common.dao.AbstractDAO;
import com.co.kr.common.vo.ExcludePageVo;
import com.co.kr.login.vo.UserAuthVo;
import com.co.kr.login.vo.UserVo;

@Repository
public class UserDao extends AbstractDAO{
	
	private final String PREFIX = "userMapper.";
	
	public int createIdCheck(String userId){
		return (int) selectOne(PREFIX + "createIdCheck", userId);
	}
	
	public int createEmailCheck(String userEmail){
		return (int) selectOne(PREFIX + "createEmailCheck", userEmail);
	}

	public void userCreateSuccess(UserVo userVo) throws Exception {
		insert(PREFIX + "userCreateSuccess", userVo);
	}

	
}

DAO도 완성을 해주겠습니다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="userMapper">

	<sql id="selectUserWhere">
		WHERE USER_ID = #{userId}
	</sql>
	
	<select id="createIdCheck" resultType="int" parameterType="String">
		SELECT COUNT(USER_ID) FROM USER_INFO
			WHERE USER_ID = #{value}
		
		/* com.co.kr.login.dao.createIdCheck */
	</select>
    
	<select id="createEmailCheck" resultType="int" parameterType="String">
		SELECT COUNT(USER_EMAIL) FROM USER_INFO
			WHERE USER_EMAIL = #{value}
		
		/* com.co.kr.login.dao.createEmailCheck */
	</select>

	<insert id="userCreateSuccess" parameterType="com.co.kr.login.vo.UserVo">
		<![CDATA[
			INSERT
			INTO USER_INFO
				(
					REGIST_NO,
					USER_ID,
					USER_NM,
					USER_EMAIL,
					USER_PW,
					USER_ZIP_CODE,
					USER_FIRST_ADDR,
					USER_SECOND_ADDR,
					REG_DE
				) VALUES (
					(SELECT NVL(MAX(REGIST_NO)+1, 1)FROM USER_INFO),
					#{userId},
					#{userNm},
					#{userEmail},
					#{userPw},
					#{userZipCode},
					#{userFirstAddr},
					#{userSecondAddr},
					TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS')
				)
		]]>
		/*com.co.kr.login.dao.userDao.userCreateSuccess*/
	</insert>
	
</mapper>

Mapper에 쿼리문을 작성해주면 끝입니다.

 

이제 회원가입을 하시고 나서 DB를 보시면 비밀번호가 암호화되서 들어온 것을 볼 수 있습니다.

 

 

Comments