POMOTODO : 회원가입 유효성검사 및 예외처리

2022. 1. 5. 00:06프로그래밍/개인프로젝트

POMOTODO를 만들면서 작성한 코드를 복습하기위해 작성하는 글입니다.

 

 

POMOTODO.kr

 

 

What is POMOTODO?


 

1-1. signup.ejs 

<form id="authForm" name="signupForm" action="/signupResult" method="post">

 

값을 받아서 signup버튼을 누르면 /signupResultpost요청

 

1-2. signup.js

 

-  id는 서버와 통신해야하기 때문에 /signup-id-check ajax요청을 통해 유효성체크를 한다

-  나머지 값들은 단순 양식에 맞는지만 확인해서 아래에 시각화 해준다

 

2. server.js

 

요청에 따라 응답코드를 전송해준다

- /signupResult

app.post('/signupResult',function(req, res){
	db.collection('users').findOne({id: req.body.loginId}, function(err,result){
		if(result == null){
			hasher({password: req.body.password}, function(err, pass, salt, hash){
				// db의 컬렉션 만들어서 데이터 저장하기
				db.collection('users').insertOne({ id : req.body.loginId, hashPassword : hash, saltPassword : salt, email : req.body.email, number : req.body.number, gender : req.body.gender,birthday : req.body.birthday, }, function(err, result){
					console.log('db user create')
				})
				db.collection('pomodoro').insertOne({ id : req.body.loginId, content: '', contentHTML:''}, function(err, result){
					console.log('db pomodoro create')
				})
				db.collection('todolist').insertOne({ id : req.body.loginId, todoList: '', todoListHTML:''}, function(err, result){
					console.log('db todolist create')
				})
				db.collection('not-todolist').insertOne({ id : req.body.loginId, notTodoList: '', notTodoListHTML:''}, function(err, result){
					console.log('db not-todolist create')
				})
				res.send("<script>alert('WELCOME !');location.href='/login';</script>");
			})
		}else{
			// console.log('아이디가 있음')
			res.send("<script>alert('this id is already in use.');location.href='/signup';</script>");
		}
	});
})

버튼을 통해 요청받은 값을 db에서 찾아서 '없다면' db의 각 컬렉션에  데이터를 만들어준다

 

 

- /signup-id-check

app.post('/signup-id-check', function(req, res){
	db.collection('users').findOne({id: req.body.id}, function(err,result){
		if(result == null){
			// 서버에 id가 없는경우
			idCheck = '';
		}else{
			idCheck = 'this id is already in use.';
		}
		res.status(200).send({ message : idCheck});
	})
})

- id는 db에서 찾아보고 없다면 공백을 응답해주고  있으면 문구를 응답해준다

- signup.js에서는 응답받은 값을 ejs에 전달해서 시각화해준다

 

 

 

느낀점

 

처음에는 버튼을 통해서만 유효성 체크만 했다.

 

하지만 사용자의 입장에서 생각했을 때 값이 중복되거나 틀렸을 경우

회원가입 양식을 처음부터 다시 작성해야된다는 불편함이 있을것이라고 생각했다

 

그래서 작성이 끝나면 바로바로 체크를 해주기 위해 코드를 변경했다

 

하지만 id는 다른사람과 중복되면 안되기 때문에 서버와 통신을 해야했고 ajax요청을 통해 예외적으로 처리했고,

나머지값들은 입력값을 제한해서 받거나 올바르게 입력했는지를 체크하기만 하고 ejs내부의 form태그를 통해

서버와 통신하도록 구현했다

 

처음 계획할 때는 생각하지 못한 문제들을 접했고 다음부터는 미리 이슈를 체크해서 두번 일하는 일이 없게 할 수 있을것같다


- 관련 코드 -

signup.ejs

//signup.ejs

<body>
    <div class="container" id="signup-container">
        <h1 class="signup-title">sign up</h1>
        <div class="signup-title-underline"></div>
        <form id="authForm" name="signupForm" action="/signupResult" method="post">
            <div class="form-list">
                <label for="id" class="label-id">id</label><br>
                <input type="text" class="form-list" id="signupId" name="loginId" placeholder="id (5~10)" minlength="5" maxlength="10" autocomplete='off' onfocus="validate()" autofocus>
                <div class="validate-id"> <%- idCheckResult %> </div>
            </div>
            <div class="form-list">
                <label for="password">password</label><br>
                <input type="password" class="form-list" id="signupPassword" name="password" placeholder="password (5~20)" minlength="5" maxlength="20" autocomplete='off'>
                <input type="password" class="form-list" id="signupPasswordCheck" name="passwordCheck" placeholder="password reapeat" minlength="5" maxlength="20" autocomplete='off'>
                <div class="message" id="password-message-match"><i class="fas fa-check"></i></div>
                <div class="message" id="password-message-unmatch">The password doesn't match</div>
                <div class="message" id="password-message-length">input in 5 to 20 characters please</div>
            </div>
            <div class="form-list">
                <label for="email" class="label-email">email</label><br>
                <input type="email" class="form-list" id="signupEmail" name="email" placeholder="email" autocomplete="off" onblur="mailCheck()">
                <div class="message" id="email-check-match"><i class="fas fa-check"></i></div>
                <div class="message" id="email-check-unmatch">input in 'e-mail format' please</div>
            </div>
            <div class="form-list">
                <label for="number" class="label-number">number</label><br>
                <input type="text" class="form-list" id="signupNumber" name="number" placeholder="only 11 numbers. (ex. 01012345678)" autocomplete='off' maxlength="11" onkeyup="onlyNumber1(this)" onchange="numberBlur(this)">
                <div class="message" id="number-message-count"><i class="fas fa-check"></i></div>
                <div class="message" id="number-message">input in only 11 'number' please</div>
            </div>
            <div class="form-list">
                <label for="birthday" class="label-birthday">birthday</label><br>
                <input type="text" class="form-list" id="signupBirthday" name="birthday" placeholder="only 6 numbers. (ex.910208)" maxlength='6' autocomplete='off' onkeyup="onlyNumber2(this)" onblur="numberBlur2(this)">
                <div class="message" id="birthday-message-count"><i class="fas fa-check"></i></div>
                <div class="message" id="birthday-message">input in only 6 'number' please</div>
            </div>
            <div class="form-list">
                <div class="gender">
                    <label class="gender-label">
                        <input type="radio" name="gender" value="male" checked="checked">
                        <span>male</span>
                    </label>
                    <label class="gender-label">
                        <input type="radio" id="signupGender" name="gender" value="female">
                        <span>female</span>
                    </label>
                </div>
            </div>
            <button type="button" onclick="signup()" class="form-list" id="form-signup">sign up</button>
            <button type="button" class="form-list" id="signup-toHome" onclick="location.href='/'">home</button>
            <button type="button" class="form-list" id="signup-toLogin" onclick="location.href='/login'">login</button>
        </form>
    
    </div>
</body>

server.js

// 서버에서 id중복체크하는 ajax요청
    app.post('/signup-id-check', function(req, res){
        db.collection('users').findOne({id: req.body.id}, function(err,result){
            if(result == null){
                // 서버에 id가 없는경우
                idCheck = '';
            }else{
                idCheck = 'this id is already in use.';
            }
        res.status(200).send({ message : idCheck});
        })
    })
    
    app.post('/signupResult',function(req, res){
        db.collection('users').findOne({id: req.body.loginId}, function(err,result){
            if(result == null){
                hasher({password: req.body.password}, function(err, pass, salt, hash){
                    // db의 컬렉션 만들어서 데이터 저장하기
                    db.collection('users').insertOne({ id : req.body.loginId, hashPassword : hash, saltPassword : salt, email : req.body.email, number : req.body.number, gender : req.body.gender,birthday : req.body.birthday, }, function(err, result){
                        console.log('db user create')
                    })
                    db.collection('pomodoro').insertOne({ id : req.body.loginId, content: '', contentHTML:''}, function(err, result){
                        console.log('db pomodoro create')
                    })
                    db.collection('todolist').insertOne({ id : req.body.loginId, todoList: '', todoListHTML:''}, function(err, result){
                        console.log('db todolist create')
                    })
                    db.collection('not-todolist').insertOne({ id : req.body.loginId, notTodoList: '', notTodoListHTML:''}, function(err, result){
                        console.log('db not-todolist create')
                    })
                    res.send("<script>alert('WELCOME !');location.href='/login';</script>");
                })
            }else{
                // console.log('아이디가 있음')
                res.send("<script>alert('this id is already in use.');location.href='/signup';</script>");
            }
        });
    })

signup.js

function signup(){
    var signupForm = document.signupForm;
    var loginId = signupForm.loginId.value;
    var password = signupForm.password.value;
    var passwordCheck = signupForm.passwordCheck.value;
    var email = signupForm.email.value;
    var number = signupForm.number.value;
    var birthday = signupForm.birthday.value;
    var gender = signupForm.gender.value;    
    if(loginId == '' || password == '' || passwordCheck == '' || email == '' || number == '' || birthday == '' || gender == ''){
        alert("Please enter all fields");
    }else{
        if(isPasswordCheck && isMailCheck && isNumberCheck && isBirthdayCheck){
            signupForm.submit();
        }else{
            if(!isPasswordCheck)
                    alert('check password')
            if(!isMailCheck)
                alert('check e-mail')
            if(!isNumberCheck)
                alert('check number')
            if(!isBirthdayCheck)
                alert('check birthday')
        }
    }
}
let isPasswordCheck;
let passwordBlur = document.querySelector("#signupPasswordCheck");
let passwordMessageMatch = document.getElementById('password-message-match');
let passwordMessageUnmatch = document.getElementById('password-message-unmatch');
let passwordMessageLength = document.getElementById('password-message-length');
passwordBlur.onblur = function (e) {
    var signupForm = document.signupForm;
    var password = signupForm.password.value;
    var passwordCheck = signupForm.passwordCheck.value;
    if(password !=='' && passwordCheck !== ''){
        if(password.length > 4){
            if(password === passwordCheck){
                passwordMessageMatch.style.display = "inline";
                passwordMessageUnmatch.style.display = "none";
                passwordMessageLength.style.display = "none";
                isPasswordCheck = true;
            }else{
                passwordMessageMatch.style.display = "none";
                passwordMessageUnmatch.style.display = "inline";
                passwordMessageLength.style.display = "none";
                isPasswordCheck = false;
            }
        }else if(password.length < 5){
            passwordMessageMatch.style.display = "none";
            passwordMessageUnmatch.style.display = "none";
            passwordMessageLength.style.display = "inline";
            isPasswordCheck = false
        }
    }
}
let isMailCheck;
function mailCheck() {
    var email = document.getElementById('signupEmail').value;
    let  emailCehckMatch = document.getElementById('email-check-match');
    let  emailCheckUnmatch = document.getElementById('email-check-unmatch');
    console.log(email);
    var regEmail = /^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/;
    if (regEmail.test(email) === true) {
        emailCehckMatch.style.display = "inline";
        emailCheckUnmatch.style.display = "none";
        isMailCheck = true;
    }else{
        emailCehckMatch.style.display = "none";
        emailCheckUnmatch.style.display = "inline";
        isMailCheck = false;
    }
}
let isNumberCheck;
let numberMessage = document.getElementById('number-message');
let numberMessageCount = document.getElementById('number-message-count');
function onlyNumber1(loc) {
    numberMessageCount.style.display = "none";
    if(/[^0123456789]/g.test(loc.value)) {
        loc.value = "";
        loc.focus();
        numberMessage.style.display = "inline";
        isNumberCheck = false;
    }
}
function numberBlur(e) {
    if(e.value.length>10){
        numberMessageCount.style.display = "inline";
        numberMessage.style.display = "none";
        isNumberCheck = true;
    }else{
        numberMessageCount.style.display = "none";
        numberMessage.style.display = "inline";  
        isNumberCheck = false;
    }
}
let isBirthdayCheck;
let birthdayMessage = document.getElementById('birthday-message');
let birthdayMessageCount = document.getElementById('birthday-message-count');
function onlyNumber2(loc) {
    birthdayMessageCount.style.display = "none";
    if(/[^0123456789]/g.test(loc.value)) {
        loc.value = "";
        loc.focus();
        birthdayMessage.style.display = "inline";
        isBirthdayCheck = false;
    }
}
function numberBlur2(e) {
    if(e.value.length>5){
        birthdayMessageCount.style.display = "inline";
        birthdayMessage.style.display = "none";
        isBirthdayCheck = true;
    }else{
        birthdayMessageCount.style.display = "none";
        birthdayMessage.style.display = "inline";
    
        isBirthdayCheck = false;
    }
}

// id중복체크 ajax요청
let idBlur = document.querySelector("#signupId");
let validatdId = document.querySelector(".validate-id");
idBlur.onblur = function (e) {
    let signupForm = document.signupForm;
    let idValue= signupForm.loginId.value;
    $.ajax({
        method : 'POST',
        url : '/signup-id-check',
        data : {id : idValue},
        success : function(data) {
            if(validatdId.style.display == 'none'){
                validatdId.style.display = 'block';
            }
            $(validatdId).html (data.message)
        },
        error : function(xhr, status, error) {
            // console.log('아이디체크 실패');
        }
    })
}
let inputId = document.querySelector('#signupId');
inputId.addEventListener(onfocus, validate);
function validate(){
    validatdId.style.display = 'none';
}