작은 프로젝트를 하면서 처음에 클라이언트 사이드 랜더링으로 구현한 후 이를 전부 서버사이드 랜더링으로 바꾸면서 클라이언트 사이드 랜더링과 서버사이드 랜더링에 대해서 학습할 수 있었다
특히 토큰을 로그아웃 시키는 방법에서 고민이 많았다. 클라이언트에서 토큰을 제거해서 무효화 시키는 방법이었는데 서버사이드 랜더링이 되면서 그가 불가능해졌다. Flask-JWT-Extended
라이브러리를 써서 이를 해결했다.
보통 이에 대해서 어떻게 해결하는지 코치님께 여쭤봤을 때는 토큰의 만기일을 변경한다고 했다.
클라이언트 사이드 랜더링, 서버사이드 랜더링
https://en.wikipedia.org/wiki/Server-side_scripting
- 서버사이드 랜더링
- 클라이언트의 각 요청에 customized된 응답을 만들어 웹서버에에서 스크립트를 제공하는 방식
- 클라이언트 사이드 랜더링
- HTML결과를 자바 스크립트를 이용해서 데이터를 주고받아 동적으로 생성해서 적용 -> 클라이언트에서 랜더링을 하는 방식
왜 서버사이드 랜더링을 써야 할까
- 고민했던 문제 :
- 왜 서버사이드 랜더링을 써야 할까
- 장점 : 유저에 따라 레이아웃을 custom하기가 용이하다 (그에 따른 html을 만들어 두면 되므로)
- 장점 : 인터페이스를 만드는 소스코드를 숨길 수 있다
- 단점 : 클라이언트가 더 많은 요청을 보내야 한다는 점 → 응답이 늦어 질 수 있고 서버에 부담이 될 수 있다
- 클라이언트 사이드 랜더링 장점 : 필요한 부분만 정보를 가져오면 된다 (초기 구동 속도는 느리지만... 페이지 읽고 + 자바스크립트 읽고+ 데이터 불러오고 + 화면 그리고 한번 불러오면 더 빠르다)
- 클라이언트 사이드 랜더링의 단점 : 검색 엔진 최적화의 문제. 자바스크립트 못읽고 HTML만 읽어서 검색엔진 최적화 하기 떄문에
세션, JWT 를 이용한 로그인
세션과 JWT토큰을 이용한 로그인의 차이점
세션을 이용한 로그인, 권한 확인
- 세션은 서버측에 저장하는 정보고, 매 요청마다 DB에 사용해 유효성 검사를 해줘야한다
- 로그인한 유저는
세션 아이디
를 받아 쿠키
에 저정한다. 해당 세션아이디를 매 요청마다 헤더에 포함해서 보낸다.
- 서버는 매 요청마다 세션을 저장한 디비를 뒤져서 유효한 접근인지를 확인하고 결과를 반환한다. DB리소스를 많이 잡아먹을 수 밖에 없다
- 매 요청마다 쿠키에 세션 아이디를 담아 보내면 서버에서는 매 요청마다 세션 아이디를 디비에 확인해서 인가를 해서 DB 리소스를 많이 잡아 먹는다
토큰
- 토큰은 토큰 값에 정보들을 담고 있어 이로 유효성 검사를 할 수 있다. 즉 토큰을 저장하는 디비를 따로 주지 않고 토큰 값 자체만으로 유효성을 체크 할 수 있다
JWT 토큰
- 3부분으로 구성되어 있다.
- 1번 : 헤더 + ALG
- 헤더(JWT토큰), ALG 알고리즘(3번의 서명값을 만드는데 필요한 알고리즘, HS256등 암호화 방식)
- 2번 페이로드 (클레임, name/value의 한 쌍으로 )
- 3번은 (1번 헤더와, 2번 페이로드, 서버에 감춰놓은 비밀 값(키값을 지정한다) 이 셋을 이 암호화 알고리즘에 돌리면 3번 서명값이 나온다)
- 서버는 요청에서 토큰 값을 받으면 1,2번 값을 서버의 비밀키와 함께 돌려서 계산된 결과값이 3번 서명값과 일치하는지 확인
- 만약 누군가가 2번을 조작한다면 요청 거부
- 3번와 서명값이 일치하고 토큰 유효값이 만료되지 않았다면 OK (인가)
토큰 다시
- db에 저장하지 않는다는 장점이 있지만 단점, 무효화할 수가 없다. 값을 클라이언트에게 줘버리기 때문에 이를 무효화할 수 없다.
- 무효화 하기 위해서는 만기일을 앞당기거나, 리프레시 토큰을 사용하는 방법이 없다.
- 리프레시 토큰
- 리프레시토큰과 access 토큰을 발급하고 refresh 토큰은 db에 저장
- 클라이언트는 access 토큰의 수명이 다하면 refresh 토큰을 보낸다
- 서버는 그 값을 저장한 것과 비교해보고 맞으면 access 토큰 새로 발급해준다
- 누군가 강제 로그아웃하고 싶으면 refresh 토큰을 db에서 지운다