이틀동안 새벽까지 열심히 프로젝트에 몰두한 결과, 나는 TIL을 그만 까먹고 말았다.
그것도 이틀이나.. 덕분에 지영 매니저님한테 따끔한 말을 듣고 책상에서 나오기 전에 미리 TIL을 작성해놓기로..
우선은 HTML(프론트)보다는 PY(백엔드)의 연결에 좀 더 집중하라는 튜터님의 조언에 맞게
좀 더 연결 부분에 초점을 두기로 했다.
불행인지 다행인지 CSS 기능 등을 부트스트랩으로 찾아낸 것에 정말 재능이 없었는데,
이론을 토대로 흐름을 읽는 것은 내 체질에 맞는 프로젝트인 듯하다.
그래서 다른 분들이 프론트 쪽을 봐주시는 동안, 나는 백엔드에 POST, GET 기능 외에도 어떤 기능이 들어가면 좋을까에 대해 아이디어를 생각해봤다.
우선은 비밀번호 암호화기능이다.
비밀번호를 mongoDB에 넣는 것은 좋지만 비밀번호를 그대로 남겨놓는 것은 보안에 취약할 수 있는 결과라고 생각했다.
그래서 보안을 설정해야 하는데 아직 그건 배우지 않아서 챗GPT에 문의를 했다.
나는 이것을 파이선에 대입하는 방법이 필요했고, 다음과 같은 코드를 얻어서 pip install bcrypt 한 다음, import bcrypt를 해서 비밀번호를 가져와서 암호화하는데 성공했다.
@app.route("/guestbook", methods=["POST"])
def guestbook_post():
count_list = db.vive02.find_one({'name': 'comment'})
count = count_list['num'] + 1
db.vive02.update_one({'name': 'comment'}, {'$inc': {'num': 1}})
name_receive = request.form['name_give']
comment_receive = request.form['comment_give']
pw_receive = request.form['pw_give']
if (name_receive == "") and (comment_receive == "") and (pw_receive == ""):
return jsonify({'msg': '저장 실패!'})
else:
doc = {
'name': name_receive,
'comment': comment_receive,
'pw': pw_receive,
'num': count
}
doc["pw"] = bcrypt.hashpw(doc["pw"].encode('UTF-8'), bcrypt.gensalt())
masked_doc = doc.copy()
masked_doc["pw"] = "********"
db.vive01.insert_one(masked_doc)
return jsonify({'msg': '저장 완료!'})
masked_doc로 복제해서 비밀번호를 온전히 변경한 다음 저장했다.
그래서 이것을 get으로 가져오기 위해
@app.route("/guestbook", methods=["GET"])
def guestbook_get():
all_comments = list(db.vive01.find({}, {'_id': False, 'pw': False}))
return jsonify({'result': all_comments})
다음의 코드를 넣었다. objectid와 pw는 필요가 없었고, pw는 인코딩 작업을 했기 때문에 jsonify 적용이 되지 않아서 빼는 게 맞았다. 이 과정에서 왜 결과값이 안 나올까 의문을 가졌는데, 파이썬에 print를 한 다음 터미널에 내가 받고자 했던 정보가 나오는지 다시금 확인해야 한다는 점을 상기했다.
그래서 아래와 같이 POST, GET은 문제가 되지 않았다.
근데 막상 이것을 삭제하려고 했는데 삭제가 안 된다.
글 쓸 때 비번을 1로 했는데, 똑같이 1을 썼는데 안 된다.
추측상의 원인은 POST 과정에서 설정한 코드의 방향이 잘못된 것 같다.
아니나 다를까 비밀번호를 암호화한 것이 아닌, 비밀번호를 '********'로 바꿔버린 것이 된 것 같다.
그래서 두 비밀번호를 비교할 때는 잠깐이나마 인코딩된 비번을 다시 디코딩하는 작업이 필요했다.
근데 이것을 어떻게 하는가?
@app.route("/guestbook", methods=["POST"])
def guestbook_post():
count_list = db.vive02.find_one({'name': 'comment'})
count = count_list['num'] + 1
db.vive02.update_one({'name': 'comment'}, {'$inc': {'num': 1}})
name_receive = request.form['name_give']
comment_receive = request.form['comment_give']
pw_receive = request.form['pw_give']
if (name_receive == "") and (comment_receive == "") and (pw_receive == ""):
return jsonify({'msg': '저장 실패!'})
else:
doc = {
'name': name_receive,
'comment': comment_receive,
'pw': pw_receive,
'num': count
}
hashed_password = bcrypt.hashpw(doc["pw"].encode('UTF-8'), bcrypt.gensalt())
decoded_password = hashed_password.decode("utf-8")
doc["pw"] = decoded_password
db.vive01.insert_one(doc)
return jsonify({'msg': '저장 완료!'})
아래와 같이 hashed_password로 수정했다. 그리고 이것을 utf-8로 디코딩 한 것을 decoded_password로 규정했다.
@app.route("/delete", methods=["POST"])
def delete_post():
num_receive = request.form['num_give']
pw_receive = request.form['pw_give']
num = int(num_receive)
delete_comment = db.vive01.find_one({"num": num})['pw']
input_pw = pw_receive.encode('utf-8')
db_pw = delete_comment.encode('utf-8')
check_pw = bcrypt.checkpw(input_pw,db_pw)
if (check_pw == True) :
db.vive01.delete_one({'num': num})
return jsonify({'msg': '삭제 완료!'})
else:
return jsonify({'msg': '비밀번호를 확인해주세요!'})
그 다음 이 디코딩된 코드를 삭제하기 위해 쓴 비밀번호와 비교했다. 이건 우리 조장인 지현님이 고생을 참 많이 하셨다.
이런 점에 있어서 머릿속으로 굴리는 기획력은 많은 경험으로 인한 지능차이인 것 같은데, 벌써부터 경험의 차이가 생긴 것 같은 기분이다. 좀 더 반성할 필요가 있지 않을까?
최종적으로 완성한 api는 다음과 같다. 다른 프론트는 내일 발표 후 올릴 생각이다.
먼저 name, comment, password를 작성하고 등록 버튼을 누르면 아래 '김철수', "안녕하세요?"와 같은 코멘트 박스가 생긴다.
그 다음 이것을 삭제하고 싶어서 삭제 버튼을 누른다면?
이렇게 중간에 패스워드 창이 하나 더 뜬다. 여기에 패스워드를 입력해서 삭제하기 버튼을 누르면, 패스워드가 맞는지 확인해보고 맞으면 삭제하게 된다.
댓글이 여러 개가 있을 때는 이것을 어떻게 구분하는 것이 좋을지? 고민을 했는데, 댓글에 번호를 0부터 입력해서 새로운 댓글이 생길 때마다 숫자를 1++한 채 부여하는 것이다.
솔직히 생각만 했고 구현은 내 능력이 아직 잘 못 받쳐줘서 아쉽지만, 코드를 보고 계속 연습해야 한다는 생각뿐이다.
이상으로 오늘의 TIL을 마친다!
'project > project' 카테고리의 다른 글
프로젝트 뭐든태그-ALLTAG (1) (0) | 2023.04.10 |
---|---|
미니 프로젝트3 : 파이썬으로 게임 만들어보기(2) (0) | 2023.03.28 |
미니 프로젝트3 : 파이썬으로 게임 만들어보기 (0) | 2023.03.28 |
미니 프로젝트 1 : 우리 조를 소개하기 (3) (0) | 2023.03.17 |
미니 프로젝트 1 : 우리 조를 소개하기 (1) (0) | 2023.03.14 |