이번에는 스프링에서 쿼리스트링을 이용한 유저아이디 중복체크를 만들어보자
실제로 존재하는 테이블을 이용하지 않고 더미 모델로 테스트를 해본다
먼저 스프링 세팅
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'
}
server:
port: 8080
servlet:
encoding:
charset: utf-8
force: true
spring:
mvc:
view:
prefix: /WEB-INF/view/
suffix: .jsp
output:
ansi:
enabled: always
@AllArgsConstructor
를 붙여서 모든 필드 값을 파라미터로 받는 생성자를 만든다@AllArgsConstructor
@Getter
@Setter
public class ResponseDto<T> {
private int code; // 1, -1
private String msg; // 사유
private T data; // 제네릭 사용으로 여러 오브젝트를 받을수 있다
}
추가적인 내용으로
@NoArgsConstructor
는 파라미터가 필요 없는 생성자를 만들어 준다@RequiredArgsConstructor
을 사용하면 필드에 final
or@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지금 코드는 불완전한데 중복체크후 submitCheck = true
일때 아이디를 변경하면 막지 못하기 때문이다.
1차적으로 막는방법은 체크후 아이디 입력폼이 변경되면 submitCheck = false
로 바꿔야하고
포스트맨으로 공격할 수도 있어서 2차적으로 서버에서 직접 체크 해야한다
회원가입 버튼을 받은 컨트롤러에서 아이디가 입력되었는지 체크하고 모델에서 DB와 중복체크를 해야한다 ( 서비스 레이어 )