청소 플랫폼 만들기 (27)
공부하며 느낀 점
참조한 페이지
const ApiError = require('../utils/apierror');
// 이메일 검증
exports.verificationEmail = (email) => {
const emailReg = /^[a-zA-Z0-9+-_.]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$/;
if (!emailReg.test(email)) {
throw new ApiError(412, '이메일 형식을 확인해주세요');
}
};
// 비밀번호 검증
exports.verificationPassword = (pass, confirm) => {
const passwordReg = /^(?!.*(.)\1\1)[a-zA-Z0-9!@#$%^&*]{4,}$/;
if (!passwordReg.test(pass)) {
throw new ApiError(
412,
'비밀번호는 네자리 이상, 영어 소문자(a~z), 영어 대문자(A~Z), 일부 특수문자(! @ # $ % ^ & *) 만 사용가능합니다.'
);
}
if (pass !== confirm) {
throw new ApiError(412, '패스워드가 일치하지 않습니다.');
}
};
// 전화번호 검증
exports.verificationPhoneNumber = (number) => {
const phoneNumberReg = /^\d{2,}-\d{3,}-\d{4,}$/;
if (!phoneNumberReg.test(number)) {
throw new ApiError(412, '전화번호 형식을 확인해주세요');
}
};
정규식을 활용한 검증을 사용하는 경우가 많아서 아예 모듈화하였다.
정말 우연치않게도 그 직후에 정규식을 고칠 일이 있어서 이득을 봤다.
(0-9
를 d
로 바꿈)
우리 프로젝트에서는 아래와 같은 방법으로 오류를 처리하고 있다.
class ApiError extends Error {
constructor(status, message) {
super(message);
this.status = status;
Error.captureStackTrace(this, this.constructor);
}
}
module.exports = ApiError;
하지만 api를 각각 나누어서 작성하다보니 에러를 처리하는 캐치문이 다 다르게 작성되어 있어서 통일 하였다.
} catch (error) {
console.error(error);
return res.status(500).json({ message: 'Internal Server Error' });
}
//////////////////////
} catch (err) {
if (err instanceof ApiError) {
console.error(err.message);
return res.status(err.status).json({ message: err.message });
}
console.error(err);
return res.status(500).json({ message: 'Internal Server Error' });
}
또한, 이제는 컨트롤러 단에서 에러를 내뱉기 때문에 서비스단의 try-catch 문을 모두 삭제하였다.
위와같이 뜨던것이 아래와같이 바뀌었다.
showModal(
'signUp',
'회원가입',
`
<form>
<div class="modal-body">
<div class="form-group">
<label for="permission" class="col-form-label">사업자/개인:</label>
<select id="signup-permission" name="선택">
<option value='guest'>일반 회원</option>
<option value='owner'>사업자 회원</option>
</select>
</div>
<div class="input-group">
<label for="signup-name">이름 </label>
<input id="signup-name" type="text" placeholder="홍길동" />
</div>
<div class="input-group">
<label for="signup-email">이메일 </label>
<input id="signup-email" type="email" placeholder="email@gmail.com" />
</div>
<div class="input-group">
<label for="signup-password">비밀번호 </label>
<input id="signup-password" type="password" placeholder="password" />
</div>
<div class="input-group">
<label for="signup-confirm-password">비밀번호 확인 </label>
<input id="signup-confirm-password" type="password" placeholder="confirm-password" />
</div>
<div class="input-group">
<label for="signup-nickname">닉네임 </label>
<input id="signup-nickname" type="text" placeholder="nickname" />
</div>
<div class="input-group">
<label for="signup-address">주소 </label>
<input id="signup-address" type="text" placeholder="XX시 XX로 XXXXX" />
</div>
<div class="input-group">
<label for="signup-phone-number">연락처 </label>
<input id="signup-phone-number" type="text" placeholder="010-XXXX-XXXX" />
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button id="signup-btn" type="submit" class="btn">Close</button>
<button type="button" class="btn btn-primary">회원 가입</button>
</div>
`
);
위와 같은 형태로 쓰던것을 아래와 같이 고쳐서 가독성을 올렸다.
const content = `
<form>
<div class="modal-body">
<div class="form-group">
<label for="permission" class="col-form-label">사업자/개인:</label>
<select id="signup-permission" name="선택">
<option value='guest'>일반 회원</option>
<option value='owner'>사업자 회원</option>
</select>
</div>
<div class="input-group">
<label for="signup-name">이름 </label>
<input id="signup-name" type="text" placeholder="홍길동" />
</div>
<div class="input-group">
<label for="signup-email">이메일 </label>
<input id="signup-email" type="email" placeholder="email@gmail.com" />
</div>
<div class="input-group">
<label for="signup-password">비밀번호 </label>
<input id="signup-password" type="password" placeholder="password" />
</div>
<div class="input-group">
<label for="signup-confirm-password">비밀번호 확인 </label>
<input id="signup-confirm-password" type="password" placeholder="confirm-password" />
</div>
<div class="input-group">
<label for="signup-nickname">닉네임 </label>
<input id="signup-nickname" type="text" placeholder="nickname" />
</div>
<div class="input-group">
<label for="signup-address">주소 </label>
<input id="signup-address" type="text" placeholder="XX시 XX로 XXXXX" />
</div>
<div class="input-group">
<label for="signup-phone-number">연락처 </label>
<input id="signup-phone-number" type="text" placeholder="010-XXXX-XXXX" />
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button id="signup-btn" type="submit" class="btn">Close</button>
<button type="button" class="btn btn-primary">회원 가입</button>
</div>
`
showModal('signUp','회원가입', content);
const user = await this.userRepository.findUserOne(userId);
if (!user) {
throw new ApiError('존재하지 않는 로그인 이메일입니다.', 401);
}
console.log(password, 'aaaaaa', passwordConfirm);
if (!password) {
password = user.password;
passwordConfirm = user.password;
}
const passwordMatch = await bcrypt.compare(password, user.password);
if (passwordMatch) {
throw new ApiError('기존 비밀번호와 다른 비밀번호를 입력해주세요.', 412);
}
console.log(password, 'bbbbb', passwordConfirm);
// 비밀번호 검증
verificationPassword(password, passwordConfirm);
let hashPassword;
if (password) {
hashPassword = await bcrypt.hash(password, );
} else {
hashPassword = user.password;
}
위와같이 새 비밀번호를 입력하지 않고 회원정보 수정시 기존 비밀번호로 업데이트 하도록 만들었다.
하지만 자꾸 비밀번호를 검증 오류가 발생했다. 이유는 이미 bcrypt 로 암호화한 것을 또 암호화해서 정규식에 맞지 않았기 때문이다...
const response = await fetch(`/api/user/me`, {
method: 'put',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
userId,
password,
passwordConfirm,
name,
nickname,
address,
phoneNumber,
}),
});
const result = await response.json();
window.location.reload();
return alert(result.message);
}
위와같이 API 응답을 받으면 새로고침을 하던것을 아래와 같이 정상적으로 요청이 완료 되었을 경우(201)에만 새로고침 하도록하여 이용자가 수정을 할 때 더 편하도록 바꾸었다.
const response = await fetch(`/api/user/me`, {
method: 'put',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
userId,
password,
passwordConfirm,
name,
nickname,
address,
phoneNumber,
}),
});
const result = await response.json();
if (response.status === 201) {
window.location.reload();
}
로그아웃쪽에서 예상지 못한 에러가 계속 일어나서 get 요청이 아니라 post 요청으로 해보니 해결되었다.
내부적으로 상태가 변하기 때문에 post가 맞다고 한다
(인프런 get post 질문)[https://www.inflearn.com/questions/258343/%EA%B0%95%EC%9D%98-%EA%B4%80%EB%A0%A8-%EC%A7%88%EB%AC%B8%EC%9D%B4-%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4]