본문 바로가기

회고록(TIL&WIL)

TIL 2022.05.04 클론코딩 팀프로젝트(BE) - 2 (회원가입, 정규표현식, 로그인, 로그아웃)

회원가입

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'
            }
        })

    }