이 블로그는 크래프톤 정글 교육과정중 개인 til을 쓰는 페이지 입니다.
최대한 검증을 할려고는 했으나 세세한 부분/디테일에서 실제와 차이가 있을 수 있으니
읽는데 참고해주시기 바랍니다.
이번 글에서 적을 3가지 주제
-jwt를 사용한 보안
-app.route/ajax를 이용한 json통신
-jinja2를 이용한 서버 사이드렌더링 구현
가 되겠다.
jwt가 뭔데?
서버는 사용자가 누구인지 모른다. 단순히 컴퓨터 프로그램들은 정보를 요청하고 보내고 받고 정해진 규정에 따라 전기신호가 움직일 뿐, ip주소가 있다고 해서 그 사용자가 누구인지 정확하게 알 수 없다는 것이다. 쉽게 말하면 쿠팡에서 배달을 시켰는데 배달기사분이 누구인지 찾아보지 않으면 모르는 것과 같다.
그래서 보안을 위해 그 사람이 누구인지 '특정시키기'위해서 어떠한 '인증서'같은걸 만들었는데 그게 jwt이다.
어떻게 특정시키는데?
우선 jwt의 구조에 대해 알아야 보자. jwt는 크게 3가지 부분으로 나뉜다.
header = 해쉬 함수와 종류를 정하는것
payload = 너가 누구인지, 언제까지 jwt토큰이 살아있을지 정하는것
signature = '특별한 키값'을 가짐. 이 값은 서버만 알고있음
뭔가 복잡해보이는데 한두번 만져보면 이해가 확 될것이다.
https://jwt.io(jwt만들어보는 사이트)
왜 특정되는데?
일단 집중해서 1줄만 읽어보자.
jwt를 만들때 인코딩을 하는데(데이터를 변환함) signature값을 모르면 슈퍼컴퓨터를 들고와도 해독이 불가능하다.
그런데 저 signature값은 누구만 안다?
-> 서버만 안다
그래서 서버를 해킹하지 않는이상 저 jwt토큰이 어떤 정보를 가졌는지 절대 알 수 없으며, 그렇기 때문에 jwt token의 주인이 누구인지 쉽게 특정 가능하다.
그럼 다 jwt만 쓰겠네?
그건 아니다. 정말 간단하고도 치명적인 단점이 있는데
다른사람이 쿠키를 탈취하는게 너무나도 쉽다는 것이다.
왜냐면 이 쿠키를 탈취한다는게 현실처럼 남이 들고있는 물건을 강도짓 하는것이 아닌
그저 통신을 훔쳐보면서 쿠키를 복사하기만 하면 되기 때문이다.
왜냐? 쿠키의 정보를 몰라도 쿠키만 들고있으면 서버는 쿠키의 주인인줄 알고
착각하기 때문이다.
@app.before_request
def token_check():
print(request.url)
token = request.cookies.get('mytoken')
print(token)
if request.url != "http://localhost:8000/":
if request.url != "http://localhost:8000/api/login":
if not token:
abort(401)
else:
사용자가 jwt 쿠키를 가지고 있는지 확인하기 위해서 썼던 코드이다.
코드를 뜯어보면
1. .before_request를 사용하여 모든 작업마다 확인하였음
2. request.cookies.get('mytoken')을 이용해 쿠키를 확인
3. 로그인할때 jwt 쿠키를 받으니 로그인/회원가입 페이지는 제외하기 위해 if사용
4. 쿠키를 가지고 있어야 하는 상황인데도 없다면 abort(401)로 작업 불가능하게 만듬
5. render_template를 쓸려고 했으나 before_request에서는 작용안한다고함
문제점이 하나 있다면 모달창을 띄울려고 할때는 url이 전달되지 않기 때문에
모달창이 그냥 떠버리는게 문제이긴 하나 어차피 모달창에서 어떠한 작업도 못하니
나름 만족하는 중이다.
우선 flask를 사용해 서버를 만들었기 때문에 python 코드는 app.route()를 많이 사용하였다.
//html 코드 //
function itemgive(){
$ajax({
type : "POST", //"POST"와 "GET"을 사용
url : "/group_buy_join",//"app.route에서 정보를 받는 url
data : {
item_type_give: 0,
item_info_give: 0,
item_url_give: $("#itemUrl").val(),
item_id_give: $("#itemName").val(),
......
}
}
## app.py 코드
from flask import flask
@app.route('/group_buy_join', methods=['POST'])
def api_item():
item_place_receive = request.form['place_give']
item_time_receive = request.form['time_give']
.....
db.item.insert_one({
'user_id' : [item_user_id_receive],
....
})
return jsonift({'result': 'success', 'msg': '물품이 정상적으로 등록되었습니다.'})
내가 썼던 ajax와 app.route의 기본적인 형태이다.
이 url이라는 것은 jwt에서 보았던 서버에서 요청하는 url이다.
jwt 코드를 보면 예외처리할때 "http://localhost:8000/" 를 제외하는것을 볼 수 있다.
이는 url코드라는것이 사이트의 위치가 아닌, "http://localhost:8000/" 를 서버에 요청했을때 결과값을 우리에게 보여준다고 생각하면 될 것 같다.
왜 이걸 알게 되었느냐?
예외처리를 local host 8000만 하고 로그인 버튼을 눌렀더니 "http://localhost:8000/api/login" 에서 abort(401)이 떠버렸다. 이후 생략되서 안적혀 있지만 회원가입/로그인 버튼을 누를때의 url도 같이 예외처리를 시키니 잘 작동하였다.
위와같은 이해를 통해 ajax-app.route 통신에 대해 적어보자면
라고 적긴 했는데 더 세세한 디테일은 잘 모르겠다.
사실 내가 적은것도 맞는건지 틀린건지 긴가민가하다.
어쨌든 확실하게 적을 수 있는것은
1. json통신은 일정한 규칙에 따라 서버와 html 사이에 정보를 교환하는 방법
2. ajax의 url과 app.rout의 url이 같아야 한다.
이거 두개라고 할 수 있겠다.
솔직히 지금 적으면서도 자신이 없다. jinja는 팀원분이 사용하신거고 프로잭트가 끝난 후 잠시 설명을 들은게 끝이기 때문이다. 그래서 개인적으로 공부를 좀 더 해보며 이해한 바를 적어보겠다.
인터넷에 html을 치면 가장 많이 보이는 밈 중 하나는
-html은 프로그래밍 언어가 아닙니다!-
일 것이다.
왜 프로그래밍 언어가 아닐까?
일단 마크업 언어의 위키 설명이다.
다음은 프로그래밍 언어의 위키 설명이다.
즉 마크업 언어란 단순히 페이지의 '틀'을 잡아주는 역할을 할 뿐인 것이고
프로그래밍 언어는 페이지를 '동적'으로 만들어주는 소프트웨어 코딩 언어인 것이다.
자 그래서 마크업 언어라는 걸 알았으니 브라우저 렌더링이라는걸 알아야 한다.
브라우저 렌더링은 뭔데?
여기서 중요한건 html, css 정보를 받아서 브라우저 화면에서 보여주는 것인데, 서버에서 받은 정보를 client(지금 이 글을 보고있는 당신)의 모니터에 띄우기 위해서는 처리과정이 필요하다.
그것을 렌더링이라고 하고, 그 렌더링 과정을 어떻게 처리하느냐에 따라 방법이 많다.
여러개가 있는데 서버사이드 렌더링만 알아보자.
정말 쉽게 말해서 렌더링을 서버에서 하는 것이다.
이 방식의 장점으로는 다음과 같다.
1. 빠르다
2. SEO(serch engine optimization)성능이 좋다
무엇보다도 가장 큰 장점은 빠르다는것이다. 두말하면 잔소리고 이것만큼 좋은것도 없다.
그리고 SEO라는것도 몰라서 찾아보니까
'웹사이트가 검색 결과에 더 잘 보이도록 최적화하는 과정'이라고 한다.
렌더링 방식이 검색 성능에도 영향을 준다는건 처음알았다.
단점 다음과 같다.
1. 서버 과부하
2. blinking issue
3. TTV/TTI 공백기
장점이 컸던만큼 단점도 엄청나다.
렌더링을 서버에서 하기 때문에 과부하가 일어나는건 당연하기도 하고 치명적인 사항이기도 하다.
유저의 편의를 위해서 기업이 가져야할 부담이 늘어난 것이고, 관리를 못하면 서버가 감당하지 못하고 뻗어버릴 수도 있다는 소리다.
blinking issue는 좀 흥미로웠다.
서버에서 렌더링을 해주기 때문에 모든 정보를 한꺼번에 받아온다.
즉 새로고침 할때마다 화면을 백지로 만들고 다시 서버로부터 정보를 받아온다는 것이다.
TTV/TTI 공백기 또한 여기서 처음 보는 것이었다.
쉽게 말하면 TTV(사이트를 볼 수 있는 시간)이 되어도 서버로부터 정보를 덜 받았을 경우
TTI(실제로 인터렉션{클릭등 활동을 하는것} 할 수 있는 시간)이 되지 않는다면 사이트가 먹통이 된다는 뜻이다.