회원가입 - 유효성검사 & 암호화

목표: 회원가입페이지를 간단하게 만들어보자!
사용한 라이브러리
front : jquery / backend : python(flask_bcrypt, flask, pymongo)
javascript , python
//front
function errorMessage(text) {
document.getElementById("signup_error").innerText =
text;
setTimeout(() => {
document.getElementById("signup_error").innerText = "";
}, 4000);
}
function Signup() {
let username = $("#username").val();
let nick = $("#nick").val();
let password = $("#password").val();
let idValCheck = /^[a-z0-9]+$/;
let pwdValCheck = /^[a-zA-Z\\d`~!@#$%^&*()-_=+]{8,24}$/;
if (username == "") {
return errorMessage('아이디를 입력해주세요.');
}
if (username.search(/\s/) != -1) {
return errorMessage("아이디에 공백이 들어갈 수 없습니다.");
}
if (!idValCheck.test(username) || username.length < 8) {
return errorMessage("아이디는 영소문자,숫자로 구성된 8글자 이상으로 조합해서 사용해주세요.")
}
if (nick == "") {
return errorMessage("닉네임을 입력해주세요.");
}
if (password == "") {
return errorMessage("비밀번호를 입력해주세요.");
}
//test() 메서드는 주어진 문자열이 정규 표현식을 만족하는지 판별하고, 그 여부를 true 또는 false로 반환한다.
//false일때
if (!pwdValCheck.test(password)) {
return errorMessage("비밀번호는 영소문자,숫자,특수문자로 구성하여 8글자~24자로 조합해서 사용해주세요.");
}
$.ajax({
type: "POST",
url: "/user/signup",
data: {user_id: username, user_pwd: password, user_nick: nick},
success: function (res) {
console.log(res);
if (res.result == "FAIL") {
let error_message = (document.getElementById(
"signup_error"
).innerText = `이미 존재하는 아이디입니다.`);
console.log(error_message);
} else {
alert("회원가입이 완료되었습니다.");
window.location.href = "/";
}
},
});
}
정규식
사용한 정규식 리터럴 | 의미 |
/^[a-z0-9]+$/ | a-z소문자 아무거나,0-9숫자 아무거나 사용할수 있다는 뜻 |
/^[a-zA-Z\\d`~!@#$%^&*()-_=+]{8,24}$/ | 영소문자,숫자,특수문자 8글자 이상 24글자 이하로 사용할 수 있다는 뜻 |
정규식은 아래와 같이 구분이 된다.
/ | (http|https|ftp|telnet|news|mms):\/\/[^\"'\s()]+ | / | i |
패턴구분자 시작 | 찾을 문자의 패턴 | 패턴구분자 끝 | 패턴변경자 |
메타문자
다른 언어에서 연산자나 예약어로 쓰이는 문자를 정규 표현식에서는 메타 문자라고 부른다. 문자열의 시작과 끝을 표시하는 메타 문자는 옵션에 따라 줄 단위나 문서 전체를 의미할 수 있다.
^ | 문자열의 시작 |
$ | 문자열의 종료 |
문자 집합과 특수 문자
이외에도 기본적으로 정의된 문자 집합과 특수 문자를 나타내는 몇가지 이스케이프 문자가 있다.
문자 집합은 대괄호 한 쌍으로 정의되는 문장이며 그 안에는 찾아야 할 문자들이 포함된다. 이때 문자 집합 내부에서 전용으로 사용되는 메타 문자가 있는데 ^는 해당 집합에 포함된 문자들을 검색에서 제외하고, 문자와 문자 사이에 -가 있을 경우 해당하는 문자 코드 범위내의 모든 문자를 포함한다.
대문자를 쓰면 해당 문자 집합을 제외하는 ^ 문자와 동일하다.
\b | 문자와 공백 사이를 의미 | \s | 공백 문자 |
\c | 제어 문자를 의미 | \t | 탭 문자 |
\d | 숫자에 해당하는 유니코드에 대응. [0-9]와 달리 아랍 문자, 페르시아 문자 등 다양한 숫자를 포괄 |
\v | 수직 탭 |
\f | 폼 피드 | \w | 단어 영문자+숫자+_(밑줄) [0-9a-zA-Z_] |
\n | 개행 문자 | \x | 16진수 값 |
\0 | 8진수 값 |
정말 진지하게 말하지만 정규식은 조금만 이해하는 것이 건강에 좋은 것 같다. 어느정도 이해하고 구글링을 하자.
#backend
from pymongo import MongoClient
from flask import Flask, render_template, jsonify, request
from flask_bcrypt import Bcrypt, generate_password_hash, check_password_hash
import certifi
ca = certifi.where()
client = MongoClient('mongodb+srv://id:password@cluster0.내주소.mongodb.net/데이터베이스이름?retryWrites=true&w=majority', tlsCAFile=ca)
db = client.dbsparta
app = Flask(__name__)
bcrypt = Bcrypt(app)
@app.route('/user/signup', methods=['POST'])
def signup():
# id, password 받아오고 저장
user_id = request.form['user_id']
user_pwd = request.form['user_pwd']
user_nick = request.form['user_nick']
pw_hash = generate_password_hash(user_pwd) #비밀번호를 암호화
# id 중복확인
if db.user.count_documents({'user_id': user_id}) == 0: #db
#db.collection.countDocuments(query, options) - db의 데이터를 카운트해서 반환함.
db.user.insert_one({'user_id': user_id, 'user_pwd': pw_hash,'user_nick':user_nick})
return jsonify({'result': 'SUCCESS', 'message': 'SIGN UP SUCCESS'})
else:
return jsonify({'result': 'FAIL', 'message': 'user_id already exists'})
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
회원가입 이벤트 순서 | front/backend | 내용 |
1 | front | 아이디 비밀번호 닉네임을 적은 후 버튼 클릭 |
2 | front | Signup 함수 실행 |
3 | front | 유효성 검사(하나라도 false시 return) |
4 | front | backend쪽으로 데이터 전송 |
5 | backend | 데이터 수신 후 비밀번호 암호화 |
6 | backend | 서버(pymongo)에 저장 후 response |
7 | backend | result결과로 true면 회원가입, false면 error메시지 |
에러메시지를 html에 뿌려주는 것과 에러메시지를 사라지게하는 것은 중복되는 코드가 예상되기에 함수를 만들어 반복해서 사용했다.
유효성검사를 하는 부분과 비동기처리를 하는 부분을 나눠서 작성하고 싶었지만 하지 못했으나 고민해보고 꼭 해보도록 하자.
또한 회원가입 버튼을 눌렀을 때 중복으로 누르지 못하도록 disabled화 시키는 것과 에러메시지도 수정해야 할 것 같다.
다음은 위의 코드가 동작하는 모습을 영상으로 업로드 해보았다.
내용은 로그인을 하고 토큰을 받아 쿠키에 저장 후 쿠키를 확인하는 내용이 함께 담겨있다.