[Spring] Ajax로 아이디 중복체크 만들기

merci·2023년 2월 1일
0

Spring

목록 보기
10/21

이번에는 스프링에서 쿼리스트링을 이용한 유저아이디 중복체크를 만들어보자
실제로 존재하는 테이블을 이용하지 않고 더미 모델로 테스트를 해본다



먼저 스프링 세팅

  • build.gradle
dependencies {
	implementation 'javax.servlet:jstl'
    implementation 'org.apache.tomcat.embed:tomcat-embed-jasper'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	compileOnly 'org.projectlombok:lombok'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
  • application.yml
server:
  port: 8080
  servlet:
    encoding:
      charset: utf-8
      force: true
spring:
  mvc:
    view:
      prefix: /WEB-INF/view/
      suffix: .jsp   
  output:
    ansi:
      enabled: always


응답데이터에 사용할 Dto 만들기

  • @AllArgsConstructor 를 붙여서 모든 필드 값을 파라미터로 받는 생성자를 만든다
@AllArgsConstructor
@Getter
@Setter
public class ResponseDto<T> {
    private int code;  // 1, -1 
    private String msg;  // 사유 
    private T data;  // 제네릭 사용으로 여러 오브젝트를 받을수 있다
}

추가적인 내용으로

  • @NoArgsConstructor 는 파라미터가 필요 없는 생성자를 만들어 준다
  • @RequiredArgsConstructor 을 사용하면 필드에 finalor@nonnull이 붙어있는 파라미터만 받는 생성자를 만들어 준다.

컨트롤러 만들기

@Controller
public class UserController {
    
    @GetMapping("/joinForm")
    public String joinForm(){
        return "joinForm";
    }

    @GetMapping("/user/usernameSameCheck")
    public @ResponseBody ResponseDto<?> check(String username){     	
        				// ? - 와일드 카드 <? extends Object>

        if( username == null || username.isEmpty()){  
            return new ResponseDto<>(-1,"username을 입력해주세요",null);
        }

        if ( username.equals("ssar")){
            return new ResponseDto<>(1,"동일한 username이 존재", false);
        }else{
            return new ResponseDto<>(1,"해당 username으로 회원가입 가능", true);
        }
    }    
}

@Controller + @ResponseBody 어노테이션이 만나면 @RestController 의 기능을 한다
@RestController 일때 스프링의 기본 전략은 json 리턴이다.
제네릭의 와일드카드( <?> )를 이용하면 어떤 타입이든 다 들어간다.

쿼리스트링에 username=ssar 을 입력하면 중복이라고 리턴하는 설정을 넣었다.
기본 설정에서 스프링은 상태코드 200만 응답한다.


뷰의 자바스크립트

중복체크 버튼을 눌렀을 때만 회원가입이 가능하도록 만들어 보자

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<form action="/join" method="post" onsubmit="return valid()">
    <input type="text" placeholder="Enter username" name="username" id="username">
    <button type="button" onclick="sameCheck()">유저네임 중복체크</button><br>
    <input type="password" placeholder="Enter password" name="password"><br>
    <input type="email" placeholder="Enter emial" name="email"><br>
    <button type="submit">회원가입</button>
</form>

폼태그에 onsubmit을 추가하면 값이 true일때 데이터를 action으로 보낸다
valid() 함수가 boolean을 리턴한다
중복체크 했을때 새로고침 되면 적어놓거 다 날라가므로 중복체크만 비동기로 확인해야 한다

<script>
  let submitCheck = false;

  function valid() {
      if (submitCheck) { // true 가 되면 회원가입 버튼 동작함
          return true;
      } else {
          alert('유저네임 중복체크를 먼저 하세요'); 
        				// 회원가입 버튼누르면 뜬다
          return false; // 회원가입 버튼을 막는다
      }
  }
  function sameCheck() {
      let username = $('#username').val()

      $.ajax({
          type: "get",
          url: "/user/usernameSameCheck?username=" + username           
      }).done((res) => {
          //console.log(res);
          if (res.data == true) {
              alert(res.msg);
              submitCheck = true; // 중복 체크 완료
          } else {
              alert(res.msg);
              submitCheck = false;
          }

      }).fail((err) => {
          console.log('상태코드 200밖에 없어서 실행 안됨')
      });
  }
</script>

ajax 의 url을 컨트롤러에서 설정한 쿼리스트링으로 만들었다
입력한 아이디에 따라 컨트롤러에서 설정한 json이 ResponseDto 로 응답된다

  • 기본
  • 중복체크 없이 회원가입 버튼을 누르면
    submitCheck = false 이므로 onsubmit 의 값이 false

    응답 json 은 -1 코드가 온다 ( 프로토콜 )
  • ssar 입력하면
  • 중복되지 않은 아이디 입력하면

지금 코드는 불완전한데 중복체크후 submitCheck = true 일때 아이디를 변경하면 막지 못하기 때문이다.

1차적으로 막는방법은 체크후 아이디 입력폼이 변경되면 submitCheck = false 로 바꿔야하고
포스트맨으로 공격할 수도 있어서 2차적으로 서버에서 직접 체크 해야한다

회원가입 버튼을 받은 컨트롤러에서 아이디가 입력되었는지 체크하고 모델에서 DB와 중복체크를 해야한다 ( 서비스 레이어 )

profile
작은것부터

0개의 댓글