일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- Strict
- 0.75px border
- ZOOM
- 0.5px border
- 서버리스 #
- Websocket
- 데이터베이스 #try #이중
- 1px border
- readonly
- 클론코딩
- 타입스크립트
- entity
- 10px
- github
- angular
- TS
- TypeScript
- 0.25px border
- Props
- 컴포넌튼
- literal
- font-size
- 전역변수
- npm
- 당근마켓
- jwt
- es6
- 문서번호
- &연산
- ES5
- Today
- Total
복잡한뇌구조마냥
코딩하면서 어려웠던 점 정리 본문
# jwt의 쿠키만료시간 설정을 위한 함수
import datetime
# 비밀번호를 암호화하기위한 함수 hashlib
import hashlib
# flask 의 기본내장함수들 = render_templaste : html 위치, request = 정보 받아오기, jsonify = 메세지보내기, session = 서버에 session값 등 저장
from flask import *
# pyjwt를 호출
import jwt
기존에 session을 통해 로그인 기능을 만들었는데 미니프로젝트로 jwt를 이용한 로그인 기능을 과제로 받았다.
jwt를 처음 운영할 때 jwt를 쓰는코드는 많은데 코드부분만 짜르니까 패키지는 안보여주더라
어디가니까 flask_jwt_extented import jwt를 사용해서 함수 쓰던데 그렇게하니까
jwt에 매니저 값을 넣는데 그거때문에 decoding, encoding 함수 둘다 안먹더라
import jwt 써서 로그인 구현하자.
시작에 앞서 session, cookie, jwt방식에 개념도 모르고 있었다.
session 방식 - 로그인 요청시 서버에서 session값을 확인하여 클라이언트에게 제공함. - 안전하고 좋으나 사용자가 많으면 서버에 부하발생 가능
cookie 방식 - 로그인 요청시 클라이언트가 가지고 있는 쿠키를 이용하여 서버에 인증받는 방식 - 보안에 취약함. 하드웨어에 있는 쿠키가 외부 유츌시 위험
jwt 방식 - 쿠키방식처럼 클라이언트에 저장하나 token을 발행하여 서버에서 암호화, 복호화 가정을 거침. 클라이언트가 토큰을 가지기 떄문에 이용자에 따른 부담이 낮음.
개념을 정리해보자면 다음처럼 현재 생각을 가지고 있다.
session의 경우 flask에 session을 import하여 서버에서 관리해주고 받아주기만 하면 간단히 해결이 되었다.
session을 사용할 때 가장 문제가 되었던 부분은
if __name__ == '__main__':
# session 사용시 지정해야할 정보 secret key지정하지않으면 동작x
# app.secret_key = 'super secret key'
# app.config['SESSION_TYPE'] = 'filesystem'
app.run('0.0.0.0', port=5000, debug=True)
코드는 맞게 짠거같은데 계속 에러가 발생하여 html이 원만히 작동하지 못했다.
이유를 알고보니 secret_key를 할당해줘야 작동하는데 2번이나 session 연습을 하면서 2번 다 작성하지않았다.
jwt에도 마찬가지로 secret_key를 할당해줘야 한다. 나는 따로 변수값으로 위에 작성하여 운영하였다.
# 토큰 유효성검사
try:
payload = jwt.decode(token_receive, SECRET_KEY, algorithms='HS256')
user_info = db.users.find_one({'userid': payload['id']})
return render_template('index.html', name=user_info['name'])
# 토큰의 유효기간이 만료되었다는 에러문구
except jwt.ExpiredSignatureError:
return redirect(url_for("login", msg="로그인 시간이 만료되었습니다."))
# 토큰이 유효하지 않다는 에러문구
except jwt.exceptions.DecodeError:
# return jsonify({'result': 'fail', 'msg': "로그인이 필요합니다!"})
return redirect(url_for("login", msg="로그인 정보가 존재하지 않습니다."))
해당 문구는 토큰 존재유무를 확인하는 유효성검사인데, 이 이분에서 에러가 계속 발생했다.
jwt.exceptions.DecodeError는 jwt의 앞부분이나 뒷부분,
추가적으로 jwt가 존재하지않는 경우까지 잡아내는 예외처리 구문이다.
해당 코드를 통해 작성을 하고 페이지에 가보면 Build에러가 발생했다. 코드는 유효한거같은데
에러코드에 token의 클레스 단위가 bytes가 아니라서 발생한다고 나오는데 아직도 이유를 모르겠다.
pw_hash = hashlib.sha256(password_receive.encode('utf-8')).hexdigest()
이게 pw를 암호화하는 부분인데 hexdigest가 16진수로 변환하는거라 그런가.. digest로 바꿔볼까하다가 하나 수정했다가 전체 마비올까봐 건들어보지는 않았다.
url_for을 빼고 jsonify로 메세지 출력으로 바꾸면 원활이 프로그램이 작동하더라...
#한칸을 더 내리면 안됨
@app.route('/login')
def login():
msg = request.args.get("msg")
return render_template('login.html', msg=msg)
해당 문구를 넣어서 login에 연결된 링크를 이렇게 바꿔주니까 작동을 했다.
단 코드를 너무 붙여서 썼더니 해당 코드를 작성하고도 구동이 되지않았다.
함수는 2칸은 내려서 쓰도록 하자...msg를 통해서 토큰처리시 발생한 msg를 받아와서 출력한다.
# 공백이 있는지 유효성검사
if (id_receive == "" or password_receive == "" or password2_receive == "" or name_receive == "" or tel_receive == "" or mail_receive == ""):
return jsonify({'msg': '작성되지 않은 정보가 있습니다.'})
해당부분은 회원가입 시 미작성부분이 있는지 유효성 검사이다. 처음에는 if .. is None 을 사용했는데 공백이라 그런지 제대로 식별하지 못했다.
그래서 is ""로 바꿔서 해봤는데 작동이 되는거같더라.
서버 구동할 때마다 맞는 문구가 아니라서 그런지 에러코드가 발생했다.(작동은 했다)
해당 문구중 하나라도 ""일 때 잡아내도록 바꾸어 버렸다. 코드가 심히 길어졌지만 한줄에 쓰고싶었다.
hashlib.sha256(inputpw_receive.encode('utf-8')).hexdigest()
아까 잠깐 얘기하긴했는데 암호화 부분이다. 코드 작성에서는 어려움이 없었으나 회원가입에 암호화 코드가 없어서 비밀번호가 너무 대놓고 나와서 어떻게 하면 고칠수 있을까 했었는데 jwt를 구현해보면서 방법을 터득했다.
token = jwt.encode(payload, SECRET_KEY, algorithm='HS256')
어느 홈페이지가 가니까 algorithm=['HS256']이라고 써져있어서 그대로 했더니 에러가 발생했다. []를 빼도록하자.
{% extends 'index.html' %}
{% block login %}
<div class="mybox">
<div class="mybucket">
<h1>로그인</h1>
<div class="form-group">
<label for="inputid">아이디</label>
<input type="text" class="form-control" id="inputid" placeholder="아이디" name="userid"/>
</div>
<div class="form-group">
<label for="inputpw">비밀번호</label>
<input type="password" class="form-control" id="inputpw" placeholder="비밀번호" name="password"/>
</div>
<button onclick="login_user()" type="submit" class="btn btn-primary">로그인</button>
<button onclick="logout_user()" type="submit" class="btn btn-primary">로그아웃</button>
</div>
{% endblock %}
jinja2 템플릿엔진을 통해서 login.html에 상속기능으로 적었다. 이렇게 하니까 코드도 짧아지고 중복문구가 줄어서 훨씬 편한 것 같다. ssr방식이 아직도 뭔지는 잘 모르겠으나 상속기능은 아주 나이스하다.
$.cookie('mytoken', response['token']);
$.removeCookie('mytoken')
토큰을 사용하기 위해서 cookie를 구워봤다. session방식만 연습하고 cookie는 안써봤는데 아마 동일 방식이겠지
처음에 해당 코드를 작성했을 때, removeCookie에는 색깔이 안들어오고 cookie에는 색깔이 들어와서 remove에서 에러가 나는줄 알았는데 디버깅 검사를 해봤는데 $.cookie는 함수가 아니란다.
뭔가 잘못됐구나 싶어서 찾아보니까 제대로 안알려주는 곳 찾기가 쉽지않더라
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
쿠키 쓸때는 해당 스크립트를 작성하도록 하자.
지금은 css프레임워크 중 효율이 좋은걸 찾고있다.
materializecss를 기반으로 제작해보려고 했는데 코드방식이 다 갈아엎어야할거같아서 포기했다.
반응형 웹으로 쓰기 좋을거같았는데 아쉬울 따름이다.
BLUMA CSS가 부트스트랩기반으로 잘 만들어진거같아서 써보려고했는데 오늘 마침 강의가 올라왔다.
오전 5시까지 혼자서 끙끙댈때는 아무것도 없는데 자고 일어나서 보니까 생겼더라
여기서도 BULMA 프레임워크를 사용하는거같으니 잘고른거같아서 강의 참고해서 열심히 해보려한다.
'이노베이션 캠프 > 회고록' 카테고리의 다른 글
알고리즘 진행 과정 중간 결산 (0) | 2022.08.10 |
---|---|
미니 프로젝트 결산 ( Sparta Travler ) (0) | 2022.08.07 |
첫번째 미니 프로젝트 github 연결 (0) | 2022.07.31 |
미니프로젝트 진행과정 정리 (0) | 2022.07.31 |
이노베이션 캠프 시작단계 (0) | 2022.07.30 |