[spring 팀프로젝트] - 웹사이트 제작 3.회원가입(+ajax 유효성 검사 아이디 중복 체크/비밀번호 암호화)

JINI·2022년 12월 5일
0
post-thumbnail

모든 항목들을 유효성 검사를 통해 회원가입이 가능하다.
그 중에서 아이디는 ajax 유효성 검사로 중복 체크 해 새로운 아이디로 가입이 가능하고 비밀번호 암호화를 통해 보안을 강화한다.

❗코드 전부를 올리기엔 너무 길기 때문에
중요하다 생각되는 필요 코드만 정리해 올리려고 한다.

🧩회원가입


1. ajax 유효성 검사로 아이디 중복 체크
2. 회원 가입시 비밀번호 암호화 저장


📕회원 dto

public class memberDTO {
	private String id;
	private String pwd;
	private String name;
	private String phone;
	private String email;
	private String sessionId;
	private Date limitTime;
}

회원가입에 필요한 회원 dto을 만들고 sql도 작성한다.
회원가입에 필요한 dto에는 아이디, 비밀번호, 이름, 번호, 이메일, 세션아이디, 쿠키로 정했는데 세션아이디와 쿠키 시간은 로그인 후 세션과 쿠키 생성을 위해 만든 것!


📕jsp

<body>
	<c:import url="../include/header.jsp"/>
	<main id="container">
		<form action="register" method="post">
			<label for="id">아이디</label> <input type="text" name="id" id="id"
						placeholder="4~12자의 영문 대소문자와 숫자만 입력">
					<button type="button" class="chk-btn" onclick="checkId()">중복확인</button>
					<label for="pwd">비밀번호</label> <input type="password" name="pwd"
						id="pwd" class="user-margin" placeholder="4~12자의 영문 대소문자와 숫자만 입력">
					<label for="pwdchk">비밀번호 확인</label> <input type="password" name="pwdchk" id="pwdchk"> 
					<label for="name">이름</label> <input type="text" name="name" id="name"> 
					<label for="phone">휴대폰 번호 (-없이)</label> <input type="tel" name="phone" id="phone"> 
					<label for="email">이메일</label> <input type="email" name="email"
						id="email" placeholder="example@gmail.com">
					<button type="submit" onclick="register();" id="join-btn">회원가입</button>
             </form>
			</div>
		</div>
	</main>
	<c:import url="../include/footer.jsp"/>
</body>

headerfooter는 반복될 코드라 줄이기 위해 파일을 따로 만들어두고 c:import로 끌어와 사용했다.

form을 사용해 post방식으로 register컨트롤러로 데이터를 전달하고 input에 회원가입에 필요한 항목들을 넣어주었다.

버튼 타입은 submit으로해야 데이터를 보내주고 클릭시 register()를 실행하고 입력란이 비어있거나 유효성 검사에 맞지않으면 경고창을 보여주고 무엇이 잘못됬는지 알려준다.


🔒1.비밀번호 암호화

비밀번호 암호화를 위해 pom.xml에 라이브러리를 추가한다.

<!-- spring-security-web -->
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>${org.springframework-version}</version><!-- 버전바꾸기-->
</dependency>

📕Controller

@Controller
@RequestMapping("member")
public class memberController implements memberLoginSession{
	@Autowired memberService ms;
	BCryptPasswordEncoder pwEncoder; //암호화

	//회원가입 페이지 연결
	@GetMapping("register_form")
	public String register() {
		return "member/register";
	}
	@PostMapping("register")
	public String register(memberDTO dto) {  //dto로 받기
		int result = ms.register(dto);
		if(result==1) {
			return "redirect:login";//성공하면 login 페이지로
		}
		return "redirect:register_form";//실패하면 다시 회원가입 폼으로 이동
	}	
}
로그인은 공통저으로 써야하기 때문에 공통 모듈을 만들어 관리했다. 
이 부분은 로그인 글에서 다룰 예정!

시작경로가 member라 공통으로 사용하기 위해 @RequestMapping을 써주었다.

회원가입시 넘어온 값들은 데이터들이 URL에 노출되면 안되기 때문에 GET 방식보다 상대적으로 보안적인 @PostMapping을 사용했다.
service로 보낼 입력값들을 result변수에 넣고 result가 1이면 회원가입 성공으로 redirect를 사용해 바로 로그인 페이지로 연결되고 실패시 다시 회원가입 페이지로 이동한다.


📕Service/serviceImpl

public interface memberService{
	public int register(memberDTO dto);
}
@Service
public class memberServiceImpl implements memberService{
	@Autowired memberMapper memberMapper; //매퍼 연결하기
	BCryptPasswordEncoder pwEncoder; //암호화

	public memberServiceImpl() {
		pwEncoder = new BCryptPasswordEncoder();
	}

	public int register(memberDTO dto) {
		//비번 암호화하기
		String securePwd = pwEncoder.encode(dto.getPwd());
		dto.setPwd(securePwd); //jsp 적용

		int result = 0;          
		String msg = "";
		try { //동일 아이디로 가입시 오류나는 것을 예외로 처리
			result = memberMapper.register(dto);
			msg = "회원가입 되었습니다";
		} catch (Exception e) {
			msg = "회원가입에 실패했습니다";
			e.printStackTrace();
		}
		return result;
	}

비밀번호를 인코딩해주는 메서드인 BCryptPasswordEncoder는 사용자의 의해 제출된 비밀번호와 저장소에 저장되어 있는 비밀번호의 일치 여부를 확인해주는 메서드를 제공하고 비밀번호를 암호화 함으로써 비밀번호 데이터가 노출되더라도 확인하기 어렵도록 만들어준다.

dto에 저장되있는 비밀번호를 가져와 암호화를 시킨 값 pwEncoder.encode(dto.getPwd());을 새로운 변수에 넣고 암호화된 비밀번호를 dto에 다시 저장한다.

입력한 데이터와 암호화한 비밀번호를 mapper로 보내고 동일 아이디로 가입시 오류나는 것을try/catch를 사용해 예외처리한다.
성공시 회원가입 메시지가 뜨고 실패시 오류 메시지가 뜬다.


📕mapper.java

public int register(memberDTO dto);

📕mapper.xml

  • 매핑 작업은 생략
<!--회원가입-->
<insert id="register">
	insert into
	box_member(buser_id,buser_pwd,buser_name,buser_phone,buser_email)
	values(#{id}, #{pwd}, #{name},#{phone},#{email})
</insert>

dto와 sql을 연결하는 매핑 작업을 해준 후에 가입을 위해 insert를 사용해 쿼리문을 작성한다.


✔️2.아이디 중복 체크

중복 확인을 클릭했을 때 새로운 아이디면 사용 가능 메시지를 중복된 아이디면 사용 불가 메시지를 출력한다.

✔️ajax 작성

<script type="text/javascript">
var idChk = 0;
function checkId(){
var id = $('#id').val(); //id값이 "inputId"인 입력란의 값을 저장
$.ajax({
    url:"idCheck", //Controller에서 요청 받을 주소
    type:"post", //POST 방식으로 전달
    data:id,
	dataType : "json", //서버로 돌려받는 값의 타입 지정
	//서버로 보낼 데이터 설정
	contentType : "application/json; charset=utf-8",

    success:function(data){ //컨트롤러에서 넘어온 cnt값을 받는다 
        if(data.cnt > 0){ 
        	alert("아이디가 존재합니다. 다른 아이디를 입력해 주세요");
            $('.chk-btn').addClass("has-error"); 
            $('.chk-btn').removeClass("has-success");
            $("#id").focus();
        } else {
        	alert("사용가능한 아이디입니다");
        	 $('.chk-btn').addClass("has-success"); 
             $('.chk-btn').removeClass("has-error");
             $("#inputPwd").focus();
             idChk=1;
        }
    },
    error:function(error){
        alert("아이디를 다시 입력해 주세요");
    }
});
};
</script>

var idChk = 0은 아이디 중복 체크 여부를 의미하고 안했을 경우 회원가입이 불가하게 처리하기 위한 변수이다.

중복 확인 버튼을 클릭했을 때 실행될 코드로 Controller에서 요청 받을 주소 url , POST 방식으로 전달하기위한 type , 서버로 돌려받는 값의 타입 dataType지정과 서버로 보낼 데이터 contentType을 설정한다.

컨트롤러에서 넘어온 data인 cnt를 받아 값이 0일 경우 해당 아이디가 존재하는 경고창을 띄우고 입력한 값은 초기화되며 1이면 사용 가능한 아이디라는 메시지가 출력된다.

입력칸을 비운 채로 중복 체크 버튼을 클릭하면 아이디를 입력하라는 경고창이 뜬다.


📕Controller

@PostMapping(value="idCheck",produces = "application/json; charset=utf8")
	@ResponseBody
	public Map<Object, Object> idCheck(@RequestBody String id){
		int count=0;
		Map<Object, Object> map = new HashMap<Object, Object>();
		count = ms.idCheck(id);
		map.put("cnt", count);
		return map;
	}

ajax에서 요청받은 idCheck 컨트롤러로 이동하고 해당 메서드 반환 타입은 map으로 해주고 String으로 변경한다.
여러 반환 타입이 있지만 그 중에서 map으로 지정했다.

주의할 점은 @ResponseBody를 꼭 추가해주어야 중복 체크의 결과가 회원가입 페이지에 반환된다.

또한 ajax 통신시 받을 데이터타입이 텍스트이기 때문에 반드시 @RequestBody 를 써준다.

중복 체크의 결과를 int 변수에 넣어 service로 보내고 그 값을 map에 담고 결과를 돌려준다.


📕Service/serviceImpl

public int idCheck(String id);
public int idCheck(String id) {
	int count = memberMapper.idCheck(id);
	return count;
}

📕mapper.java

public int idCheck(String id);

📕mapper.xml

<!-- 아이디 중복체크 -->
<select id="idCheck" parameterType="String" resultType="Integer">
	select
	count(*) from box_member where buser_id = #{userId}
</select>

조회 결과 값을 저장하기 위한 데이터 타입으로 resultType은 Integer로 전달받은 파라이터 데이터 타입 지정은 paramterType은 String이다.


profile
꾸준히 성장하는 개발자

0개의 댓글