흐름 👀
- 비밀번호 인증 -> 완료 시, 버튼 변경 (로그인 계정의 비밀번호와 비교)
- 유효성검사 -> 완료 시, 버튼 변경
- 전송하기 -> 1,2번 완료 시, flask에서 DB에 주민등록번호 추가/변경
결과화면 👀

1. HTML(전체) 📝
<div class="form_area">
<div class="idpw_area">
<h3><label for="username" class="margin25">아이디</label></h3>
<input type="text" id="username" name="username" disabled value="{{ g_user }}">
<h3><label for="password" class="margin25">비밀번호</label></h3>
<input type="password" id="password" name="password">
<span class="error_box" id="pw_error">비밀번호가 맞지 않습니다.</span>
<div class="pwval_area">
<h3><label for="pw_btn" id="pw_label">비밀번호 확인</label></h3>
<input type="submit" id="pw_btn" name="pw_btn">
</div>
</div>
<div class="joo_area">
<div class="joo_area_label">
<h3><label for="fir_joo">주민등록번호</label></h3>
<span class="alert_box point_color">변환된 주민등록번호를 확인해주세요.</span>
</div>
<div class="joo_area_input">
<input type="text" id="fir_joo" name="fir_joo" value="{{ fir_joo }}"
maxlength="6" onkeyup="this.value=this.value.replace(/[^0-9]/g,'');">
<input type="text" id="sec_joo" name="sec_joo" value="{{ sec_joo }}"
maxlength="7" onkeyup="this.value=this.value.replace(/[^0-9]/g,'');">
</div>
<span class="error_box" id="joo_error">주민등록번호가 유효하지 않습니다.</span>
<div class="val_area" >
<h3><label for="val_btn" id="val_label">유효성검사</label></h3>
<input type="submit" id="val_btn" name="val_btn">
</div>
</div>
</div>
2. JavaScript(전체) 📝
window.addEventListener('load', ()=> {
const pw_input = document.querySelector("#password");
const pw_btn = document.querySelector("#pw_btn");
const pw_area = document.querySelector(".pwval_area");
const pw_label = document.querySelector("#pw_label");
const pw_error = document.querySelector("#pw_error");
let pw_status = true;
pw_btn.addEventListener('click', ()=> {
const postdata = {
'password':pw_input.value, 'kind': 'password'
}
$.ajax({
type: 'POST',
data: JSON.stringify(postdata),
dataType : 'JSON',
contentType: "application/json",
success: function(result){
successAlert();
disabled(pw_input, false, pw_btn, pw_area, pw_label, pw_error);
pw_status = false;
},
error: function(result){
failedAlert();
error_msg(pw_input, false, pw_error);
}
})
});
const joo_input1 = document.querySelector("#fir_joo");
const joo_input2 = document.querySelector("#sec_joo");
const joo_btn = document.querySelector("#val_btn");
const joo_area = document.querySelector(".val_area");
const joo_label = document.querySelector("#val_label");
const joo_error = document.querySelector("#joo_error");
let joo_status = true;
joo_btn.addEventListener('click', ()=> {
document.querySelector(".alert_box").style.display = "none";
let joomin = joo_input1.value + joo_input2.value;
joomin = joomin.split('');
const weight = [2,3,4,5,6,7,8,9,2,3,4,5];
for(let i=0; i<joomin.length-1; i++){
joomin[i] = joomin[i] * weight[i];
}
const last_joo = joomin[joomin.length-1];
let sum = 0;
for(let i=0; i<joomin.length-1; i++){
sum += joomin[i];
}
sum = sum % 11;
sum = 11 - sum;
if (sum > 9){
sum = sum % 10;
}
if(sum == last_joo){
successAlert();
disabled(joo_input1, joo_input2, joo_btn, joo_area, joo_label, joo_error);
joo_status = false;
const postdata = {
'kind': 'joo'
}
$.ajax({
type: 'POST',
data: JSON.stringify(postdata),
dataType : 'JSON',
contentType: "application/json",
success: function(result){
},
error: function(result){
ajaxAlert(false);
}
})
}
else {
failedAlert();
error_msg(joo_input1, joo_input2, joo_error);
}
});
const sub_btn = document.querySelector("#submit");
sub_btn.addEventListener('click', ()=> {
if(pw_status==false && joo_status==false){
const postdata = {
'fir_joo': joo_input1.value, 'sec_joo': joo_input2.value, 'kind': 'submit'
}
$.ajax({
type: 'POST',
data: JSON.stringify(postdata),
dataType : 'JSON',
contentType: "application/json",
success: function(result){
window.location.href = '/ocr/check/'
},
error: function(result){
ajaxAlert(false);
}
})
}
else {
subAlert();
}
});
joo_input1.addEventListener('input', ()=>{
if(joo_input1.value.length>5){
joo_input2.focus();
joo_input2.select();
}
});
function disabled(input1, input2, btn, area, label, error){
if(input2){
input1.disabled=true;
input2.disabled=true;
}
else {
input1.disabled=true;
}
btn.disabled=true;
area.disabled=true;
error.style.display = "none";
label.innerHTML = "인증완료";
label.style.cursor = "default";
area.style.color = "#3e6595";
area.style.backgroundColor = "#f9f9f9";
area.style.border = "0.8px solid #3e6595";
area.style.cursor = "default";
}
function error_msg(input1, input2, error){
if(input2){
input1.value="";
input2.value="";
}
else {
input1.value="";
}
error.style.display = "flex";
}
function successAlert(){
Swal.fire({
icon: 'success',
title: '인증성공',
text: '인증되었습니다.',
confirmButtonColor: '#2b70f8',
width: '25rem',
});
}
function failedAlert(){
Swal.fire({
icon: 'error',
title: '인증실패',
text: '다시 입력해주세요.',
confirmButtonColor: '#2b70f8',
width: '25rem',
});
}
function subAlert(){
Swal.fire({
icon: 'error',
title: '인증실패',
text: '인증을 먼저 해주세요.',
confirmButtonColor: '#2b70f8',
width: '25rem',
});
}
function ajaxAlert(text){
if(text == true){
Swal.fire({
icon: 'success',
title: 'Success',
text: 'ajax success!',
confirmButtonColor: '#2b70f8',
width: '25rem',
});
}
else {
Swal.fire({
icon: 'error',
title: 'Fail',
text: 'ajax failed',
confirmButtonColor: '#2b70f8',
width: '25rem',
});
}
}
});
3. Python(FLASK) 📝
@bp.route('/print/', methods=['POST', 'GET'])
def print():
if request.method == 'POST':
user = User.query.filter_by(username=g.user.username).first()
if request.get_json():
result = request.get_json()
if result['kind'] == 'password':
password = result['password']
if check_password_hash(user.password, password):
return jsonify(result="success", data=result)
else:
return jsonify(result="error", data=result), 500
elif result['kind'] == 'joo':
return jsonify(result="success", data=result)
elif result['kind'] == 'submit':
user.fir_joo = result['fir_joo']
user.sec_joo = result['sec_joo']
db.session.commit()
return jsonify()
else:
return jsonify(result="error"), 500
else:
...
- 비동기 통신이 아닐 경우 밑에 있는 함수는 관련이 없어서 생략했다.
- 라이브러리도 생략했다.