회원가입
1) 기간
2022.05.04~ 2022.05.05
2) 이슈 설명
회원 가입 시 입력 받은 데이터 값을 DB에 저장
3) 세부 구현 순서
- 아이디(이메일), 패스워드, 이름, 닉네임 값을 받아오기
- 패스워드 hash함수 이용하여 암호화한 뒤
- DB에 받아온 값과 추가로 필요한 컬럼 기본값 입력하여 DB 에 저장
- 회원가입 메세지 출력 후 로그인 창으로 이동
4) 추가 구현 사항
- 아이디 중복 체크
- 공백 없도록 입력 값 체크
- 정규표현식을 이용한 아이디 패스워드 입력 값 점검
git 이슈 단위로 관리 중인 업무
https://github.com/SeonminKim1/lucky-seven/issues
GitHub - SeonminKim1/lucky-seven
Contribute to SeonminKim1/lucky-seven development by creating an account on GitHub.
github.com
오늘은 맡은 회원가입/로그인 기능을 구현하는 것으로 하루를 보냈다. JAVA와는 다른 구성인 듯 하면서 비슷한 부분이 많아서 금방할 수 있을 거라 생각했지만, 아무래도 DB도 새로운 것을 쓰고 서버도 flask를 처음 써보다 보니 사용법에 약간의 차이도 있었고 또 오래전에 사용했던거라 대부분 까먹어서 다시 공부하는데 시간을 많이 들인 것 같다.
그래도 다시 한번 코드를 작성해보면서 복습도 되었고 제로에서부터 떠올리진 못해도 보고 읽을 수 있는 정도까진 되어있어서 그나마 레퍼런스를 참고해서 코드를 짜는 데 있어서는 수월했었던 것 같다.
정규표현식을 이용한 입력 값 판별
//모든 공백 체크 정규식
var empJ = /\s/g;
//아이디 정규식
var idJ = /^[a-z0-9]{4,12}$/;
// 비밀번호 정규식
var pwd_regExp = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,20}$/;
// 이름 정규식
var nameJ = /^[가-힣]{2,6}$/;
// 이메일 검사 정규식
var mailJ = /^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$/i;
// 휴대폰 번호 정규식
var phoneJ = /^01([0|1|6|7|8|9]?)?([0-9]{3,4})?([0-9]{4})$/;
다시만난 정규표현식...
이 정규표현식을 이용하여 ajax에서 비동기식으로 id 값 판별에 사용
$(document).ready(function () {
// id 값을 입력했을 때
$('#id').blur(function () {
let id = $('#id').val()
// 입력받은 값 중 입력하지 않은 값이 있을 경우
if (id == "") {
$('#id_check').html('<i class="fa-solid fa-circle-exclamation"></i>')
return;
} else {
$('#id_check').text('')
}
// 정규 표현식을 이용한 아이디 형식 제한
let id_regExp = /^[a-zA-Z0-9]{4,12}$/;
if (!id_regExp.test(id)) {
$('#id_check').html('<i class="fa-regular fa-circle-xmark"></i>')
return;
} else {
$('#id_check').html('<i class=\"fa-regular fa-circle-check\"></i>')
return;
}
정규표현식을 변수에 저장한 다음 .test(input값) 함수를 사용해서 boolean 값 리턴받아서 if문에서 사용하는 방식
비동기식으로 값을 입력하거나 수정할 때 마다 갱신되도록 $('선택자').blur(function () { ... } 안에서 판별하게 했고
그에 따른 결과 값으로 font awesome 아이콘 출력하기 위해서 $('선택자').html('태그') 를 사용했다.
ajax통해서 데이터를 전달한 것을 flask에서 받아서 아이디 중복확인하고, 패스워드는 암호화하여
연결된 mongoDB에 짜둔 DB TABLE에 맞게 값 저장
app.py
# 회원가입 입력받은 값을 받아 DB에 추가하기
@app.route("/join", methods=["POST"])
def signup():
id_receive = request.form['id_give']
name_receive = request.form['name_give']
nick_receive = request.form['nick_give']
pwd_receive = request.form['pwd_give']
# 입력받은 패스워드 값 해싱하여 암호화
hashed_pw = hashlib.sha256(pwd_receive.encode('utf-8')).hexdigest()
id_dup = bool(db.USER.find_one({'id': id_receive}))
# 아이디 중복 여부 체크
if id_dup:
return jsonify({'result': 'success','exist': id_dup, 'msg': '중복된 아이디 입니다.'})
else:
doc = {
'id': id_receive,
'pwd': hashed_pw,
'name': name_receive,
'nickname': nick_receive,
'follower': [],
'following': [],
'profile_img': ''
}
db.USER.insert_one(doc)
return jsonify({'result': 'success', 'msg': '회원 가입 완료'})
중복 체크 할때 return 값으로 'exist' : id_dup 을 줌으로써 ajax에서 response 받아와서 중복인 상황을 처리할 수 있게 만들었다.
join.html 에서 ajax script 부분
function join() {
// 입력한 값들 가져와 변수에 저장
let id = $('#id').val()
let name = $('#name').val()
let nick = $('#nickname').val()
let pwd = $('#pwd').val()
$.ajax({
type: "POST",
url: "/join",
data: {'id_give': id, 'name_give': name, 'nick_give': nick, 'pwd_give': pwd},
success: function (response) {
// 아이디가 중복일 경우
if (response['exist']) {
alert(response["msg"])
} else {
alert(response["msg"])
window.location.replace('/')
}
}
})
}
로그인
user.js
// Login
function login() {
let id = $('#id').val()
let pwd = $('#pwd').val()
$.ajax({
type: "POST",
url: "/user/api/login",
data: {'id_give': id, 'pwd_give': pwd},
success: function (response) {
alert(response['msg'])
if (response['result'] == 'success') {
// 토큰이 정상적으로 발급되면, 'token' 토큰을 받아 쿠키에 저장
// 토큰 최상위 경로에 쿠키 저장
document.cookie = 'mytoken=' + response['token'] + ';path=/'
window.location.replace('/')
} else {
// 로그인 실패 시
window.location.replace('/user/login')
}
}
})
}
user.py
# 로그인 id, pwd 값 받아와서 판별 후 토큰 생성
@bp.route("/api/login", methods=["POST"])
def api_login():
id_receive = request.form['id_give']
pwd_receive = request.form['pwd_give']
# 입력받은 패스워드 값 해싱하여 암호화
hashed_pw = hashlib.sha256(pwd_receive.encode('utf-8')).hexdigest()
# DB에 저장된 값 가져오기
user = db.USER.find_one({'id': id_receive, 'pwd': hashed_pw})
print(user)
if user is not None:
# JWT(Json Wep Token)생성
# 토큰을 풀었을 때 얻을 수 있는 id 값과, 유효기간(exp)를 담음
payload = {
'id': id_receive,
'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=1800)
}
# 토큰 생성 payload의 값 인코딩, 암호키 필수 유출금지!, 암호화형태 지정
token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')
return jsonify({'result': 'success', 'token': token, 'msg': '로그인 성공'})
else:
return jsonify({'result': 'fail', 'msg': '아이디 또는 비밀번호가 일치하지 않습니다.'})
로그아웃
// 로그아웃
function logout() {
$.ajax({
type: "GET",
url: '/logout',
data: {},
success: function (response) {
$.removeCookie('mytoken');
{#alert(response['msg'])#}
window.location.href = '/login'
}
})
}
'회고록(TIL&WIL)' 카테고리의 다른 글
TIL 2202.05.08 클론코딩 팀프로젝트(BE) - 4 (request body, 매직 메서드, list빼기함수, 파이썬 list랜덤 추출) (0) | 2022.05.08 |
---|---|
TIL 2022.05.06 클론코딩 팀프로젝트(BE) - 3 (중간점검, 중복확인, 입력값 확인, 타임어택) (0) | 2022.05.06 |
TIL 2022.05.03 클론코딩 팀프로젝트(BE) - 1 (hashlib, JWT, git) (0) | 2022.05.03 |
TIL 2022.05.02 인스타그램 클론 코딩 - 3 (KPT 회고, 미디어쿼리) (2) | 2022.05.02 |
TIL & WIL 2022.04.29 인스타그램 클론코딩 - 2 (0) | 2022.04.29 |