항해 WIL - 개발자로서의 1 주차

2022. 11. 20. 15:37항해99/항해99

이제 한주가 흘렀다.

 

이번 주는 풀스택 미니 프로젝트가 시작되었는데  

우리 팀의 이번 미션은 운동커뮤니티 페이지를 만드는 것이다.

 

여기서 나는 팀장으로 선택되었고 로그인과 계정관리 파트를 맡게되었다.

 

내가 사용한 계정관련 API에는 JWT 토큰을 사용했으며 코드는 아래와 같다.

@app.route('/')
def home():
    token_receive = request.cookies.get('mytoken')
    try:
        payload = jwt.decode(token_receive, SECRET_KEY, algorithms=['HS256'])
        user_info = db.user.find_one({"id": payload['id']})
        return render_template('index.html', nickname=user_info["nick"],point=user_info["point"])

    except jwt.ExpiredSignatureError:
        return redirect(url_for("login", msg="로그인 시간이 만료되었습니다."))
    except jwt.exceptions.DecodeError:
        return render_template('index.html')


#################################
##  로그인을 위한 API            ##
#################################

# [회원가입 API]
# id, pw, nickname을 받아서, mongoDB에 저장합니다.
# 저장하기 전에, pw를 sha256 방법(=단방향 암호화. 풀어볼 수 없음)으로 암호화해서 저장합니다.
@app.route('/api/join', methods=['POST'])
def api_register():
    id_receive = request.form['userid_give']
    pw_receive = request.form['userpw_give']
    nickname_receive = request.form['nickname_give']

    pw_hash = hashlib.sha256(pw_receive.encode('utf-8')).hexdigest()

    id_check = db.user.find_one({'id': id_receive}, {'_id': 0})
    nick_check = db.user.find_one({'nick': nickname_receive}, {'_id': 0})
    if id_check != None :
        return jsonify({'result': 'id error'})
    elif nick_check != None:
        return jsonify({'result': 'nick error'})
    else :
        db.user.insert_one({'id': id_receive, 'pw': pw_hash, 'nick': nickname_receive, 'point': 0, 'tier': 1})
        return jsonify({'result': 'success'})


# [로그인 API]
# id, pw를 받아서 맞춰보고, 토큰을 만들어 발급합니다.
@app.route('/api/login', methods=['POST'])
def api_login():
    id_receive = request.form['id_give']
    pw_receive = request.form['pw_give']

    # 회원가입 때와 같은 방법으로 pw를 암호화합니다.
    pw_hash = hashlib.sha256(pw_receive.encode('utf-8')).hexdigest()

    # id, 암호화된pw을 가지고 해당 유저를 찾습니다.
    result = db.user.find_one({'id': id_receive, 'pw': pw_hash})

    # 찾으면 JWT 토큰을 만들어 발급합니다.
    if result is not None:
        # JWT 토큰에는, payload와 시크릿키가 필요합니다.
        # 시크릿키가 있어야 토큰을 디코딩(=풀기) 해서 payload 값을 볼 수 있습니다.
        # 아래에선 id와 exp를 담았습니다. 즉, JWT 토큰을 풀면 유저ID 값을 알 수 있습니다.
        # exp에는 만료시간을 넣어줍니다. 만료시간이 지나면, 시크릿키로 토큰을 풀 때 만료되었다고 에러가 납니다.
        payload = {
            'id': id_receive,
            'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=30)
        }
        token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')

        # token을 줍니다.
        return jsonify({'result': 'success', 'token': token})
    # 찾지 못하면
    else:
        return jsonify({'result': 'fail', 'msg': '아이디/비밀번호가 일치하지 않습니다.'})

# [탈퇴 API]
@app.route('/api/leave', methods=['POST'])
def api_leave():
        token_receive = request.form['token_give']
        pw_receive = request.form['pwconfirm_give']
        payload = jwt.decode(token_receive, SECRET_KEY, algorithms=['HS256'])
        

        pw_hash = hashlib.sha256(pw_receive.encode('utf-8')).hexdigest()
        userinfo = db.user.find_one({'id': payload['id']}, {'_id': 0})
        if pw_hash == userinfo['pw']:
            db.user.delete_one({'id':payload['id']})
            return jsonify({'result': 'success'})
        else :
            return jsonify({'result': 'fail'})

# [비번변경 API]
@app.route('/api/pwchange', methods=['POST'])
def api_pwchange():
        token_receive = request.form['token_give']
        pw_receive = request.form['pw_give']
        new_pw_receive = request.form['new_pw_give']
        payload = jwt.decode(token_receive, SECRET_KEY, algorithms=['HS256'])

        #받아온 원래 패스워드
        pw_hash = hashlib.sha256(pw_receive.encode('utf-8')).hexdigest() 
        #새로운 패스워드
        new_pw_hash = hashlib.sha256(new_pw_receive.encode('utf-8')).hexdigest()
        
        #db에 저장된 원래 패스워드 
        pw_original = db.user.find_one({'id': payload['id']}, {'_id': 0})['pw']

        if pw_hash == pw_original:
            db.user.update_one({'id':payload['id']},{'$set':{'pw':new_pw_hash}})
            return jsonify({'result':'success' })
        else :
            return jsonify({'result': 'fail'})

# [닉네임변경 API]
@app.route('/api/nicknamechange', methods=['POST'])
def api_nickchange():
        token_receive = request.form['token_give']
        nick_receive = request.form['nickname_give']
       
        payload = jwt.decode(token_receive, SECRET_KEY, algorithms=['HS256'])
        nickname_check = db.user.find_one({'nick': nick_receive}, {'_id': 0})
  
        if nickname_check == None:
            db.user.update_one({'id':payload['id']},{'$set':{'nick':nick_receive}})
            return jsonify({'result':'success' })
        else :
            return jsonify({'result': 'fail'})  


#[닉네임 체크용]
@app.route('/api/nickcheck', methods=['POST'])
def api_nickcheck():
        token_receive = request.form['token_give']
        payload = jwt.decode(token_receive, SECRET_KEY, algorithms=['HS256'])
        nickname_check = db.user.find_one({'id': payload['id']}, {'_id': 0})['nick']
        return jsonify({'nick': nickname_check})

 

이렇게 백엔드쪽에서 대부분의 처리가 이루어져 클라이언트쪽에서는 부담이 덜 가게끔 해보았다.

아직 미숙하지만

앞으로는 '어떻게 하면 더 빨리 프로그램이 돌아갈까?' 라는 생각을 계속해서 더욱 발전된 개발자가 될 것이다.

 

 

 

우리 2조의 결과물이다.ㅎㅎㅎ 뿌듯( 하지만 시간이 4일로 너무 짧았다... 그래서 부족한 점도 많다...)

 

한주의 챌린지를 함께하고 특정레벨의 인원들이 해당 챌린지 영상을 평가하여 인증을 해주고

인증이 3개가 넘어가면 해당 챌린지 글의 작성자의 점수가 올라가고 그것이 랭크에 반영되는 체계이다.

 

원래는 커뮤니티 게시판을 먼저 만들고 챌린지 게시판을 추후에 만들 계획이었지만 시간이 생각보다 너무 짧았다.

 

만약 한 2주정도의 시간이 있었다면 해볼만한 내용으로는

1.커뮤니티 게시판만들기

2. 댓글 기능

3. 비디오 플레이어 구현 및 데이터베이스에 비디오 저장

4. 시큐어 코딩 ( 타 팀 발표시 매니저님께서 게시판에 인젝션 공격을 하자 바로 뚫리는 모습이 보였다.)

 


[1주차 느낀점]

 

항해99를 처음 시작하며 처음으로 협업이라는 것을 해봤고 그것이 생각처럼 쉽지는 않다는 것이었다.

항해의 기본적인 목표는 협업을 잘하는 개발자라는 느낌을 받았는데

앞으로는 계속해서 팀을 바꿔가며 여러 종류의 사람들과 같이 팀이 될 것이다.

나에게 잘 맞는 사람도 있을 것이고 안 맞는 사람도 있을 것이지만 

자고로 협업을 잘하는 사람이란 나와 안 맞는 사람과도 협업을 능숙하게 하는 사람이라고 생각하기에

앞으로 더욱 협업을 잘할 수 있도록 내 실력과 인성을 갈고 닦는 노력이 필요할 것으로 보인다! 파이팅!!

 

 

아쉽기도 하고 후련하기도 한 이번 미니프로젝트는 이제 뒤로한채

2주차!!! 프로그래밍 기초 주차에서 알고리즘 문제를 풀 시간이다.

 

앞으로도 더 힘차게 달려가보자!