현재 회원가입화면이다.
그림에 있는 것과 같이 이름아래 email부분과 password부분에 그냥 문자를 넣어도 가입이 된다.
이 부분을
1. email형식 체크
2. password의 유효성 체크
3. 비밀번호 확인
4. Database 내 중복이메일 체크
까지 처리를 해야 할 것 같다. (당장에 돌아는 가지만 배우는 입장이니 이것저것 다 해본다.)
우선 유효성을 확인 할 함수를 담은 파일을 만든 후 내보내준다.
export function isEmail(asValue) {
var regExp = /^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/i;
return regExp.test(asValue); // 형식에 맞는 경우 true 리턴
}
export function isPassword(asValue) {
var regExp = /^(?=.*\d)(?=.*[a-zA-Z])[0-9a-zA-Z]{8,10}$/; // 8 ~ 10자 영문, 숫자 조합
return regExp.test(asValue); // 형식에 맞는 경우 true 리턴
}
유효성 확인 함수를 signup.js에 import해준 뒤 state에서 email과 password를 넣어 유효성 검사를 해준다.
여기서 email과 password를 적을 때 마다 확인하기보다 일정한 시간이 지난 뒤 (글자를 어느 정도 적고 난 뒤) 유효성 확인을 하고 싶은데 이 부분에서 어떻게 처리해야할지에 대해 고민이 생겼다. debounce를 사용해야 할 것 같아 여러 참고문서를 확인 한 뒤 적용해 보았다.
우선 state내 email이 유효한지 여부를 확인할 isValidEmail이라는 것을 추가하고
일정 시간이 지난 뒤 state 내 email을 유효성 함수에 넣을 함수를 작성해 보았다.
checkValidEmail = () => {
let timer;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
if (!isEmail(this.state.email)) {
this.setState({ isValidEmail: false });
} else {
this.setState({ isValidEmail: true });
}
}, 500);
};
그리고 이 함수를 email의 state가 변경되는함수에 setState된 뒤 실행하도록 넣어준다.
createEmail = e => {
// console.log("사인업 이메일: ", e.target.value);
const __email = e.target.value;
this.setState({ email: __email });
this.checkValidEmail(); //함수 실행
};
그리고 this.isValidEmail이 true/false일 때 각각의 알림메세지를 작성해 준다.
<div>
<input
value={this.state.email}
type="email"
placeholder="Email"
onChange={e => this.createEmail(e)}
/>
{this.state.email ? (
this.state.isValidEmail ? (
<span style={{ color: "blue" }}>사용가능한 email입니다.</span>
) : (
<span style={{ color: "red" }}>유효하지 않은 email입니다.</span>
)
) : null}
</div>
비밀번호도 이메일과 같은 방식으로 한다.
이미지삽입
1, 2번 완료
비밀번호 재확인도 위의 진행과정과 비슷하다.
다른 점은 일정시간이 지난 후 유효성 함수내에서 이메일과 비밀번호 유효여부를 확인하는 대신 password와 재확인 password가 같은지 여부를 확인해주면 된다.
//일치여부 확인함수
checkMatchPassword = () => {
let timer;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
if (this.state.password === this.state.passwordCheck) {
this.setState({ isMatchPassword: true });
} else {
this.setState({ isMatchPassword: false });
}
}, 500);
};
//렌더링
<div>
<input
value={this.state.passwordCheck}
type="password"
placeholder="Check Password"
onChange={e => this.repeatPassword(e)}
/>
{this.state.passwordCheck ? (
this.state.isMatchPassword ? (
<span style={{ color: "blue" }}>비밀번호 확인완료</span>
) : (
<span style={{ color: "red" }}>
비밀번호가 일치하지 않습니다.
</span>
)
) : null}
</div>
3번 완료
email 중복확인은 우선 중복확인 버튼을 만든 후 클릭이벤트에 ajax요청을 보내야한다.
client를 수정하고 server에 API를 만든 후 database에 중복여부를 확인 후 메세지를 보여줘야한다.
우선 server에서 API를 만들어 준다.
서버의 controller를 만들어 요청과 응답, 그리고 에러를 분기해준 뒤 model에서 database에 보낼 query문을 보낸다.
===SERVER===
//Controller (user.js)
checkEmail: (req, res) => {
if (!req.body.email) {
res.status(400).send({
error: {
status: 400,
message: "요청에 빠진내용을 확인해주세요 {email}."
}
});
} else {
let arg = {
email: req.body.email
};
userModel.checkEmail(arg, (err, result) => {
if (err) {
res.status(500).send({
error: {
status: 500,
message: "이메일 중복확인 실패"
}
});
} else {
if (!result.length) {
//결과값이 비어있다면 중복된 값이 없는 것이다.
res.status(200).send({ message: "사용가능한 email입니다." });
} else {
//결과값이 있다면 이미 가입된 email이다.
res.status(409).send({
error: {
status: 409,
message: "이미 가입된 email입니다."
}
});
}
}
});
}
}
//Model (userModel.js)
checkEmail: ({ email }, callback) => {
const query = `SELECT id FROM users WHERE email='${email}';`;
//Database에 요청email이 있는 id값을 요청
connection.query(query, (err, result) => {
if (err) {
return callback(err, null);
} else {
return callback(null, result);
}
});
}
===CLIENT===
// 서버에 아이디 중복확인 요청 함수
checkDuplicateEmail = () => {
if (this.state.isValidEmail) {
let body = {
email: this.state.email
};
console.log("바디", body);
api("/user/checkEmail", "POST", body)
.then(res => alert(res.message))
.catch(err => {
if (err.status === 409) {
alert(err.message);
this.setState({
email: "",
isValidEmail: !this.state.isValidEmail
});
} else {
console.log(err.message);
}
});
}
};
//렌더링 코드
<div>
<input
value={this.state.email}
type="email"
placeholder="Email"
onChange={e => this.createEmail(e)}
/>
<button onClick={this.checkDuplicateEmail}>중복확인</button>
{this.state.email ? (
this.state.isValidEmail ? (
<span style={{ color: "blue" }}>사용가능한 email입니다.</span>
) : (
<span style={{ color: "red" }}>유효하지 않은 email입니다.</span>
)
) : null}
</div>
이미 가입된 이메일 확인
새로운 이메일 확인
4번 완료