일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- DFS & BFS
- 분할 정복(Divide and Conquer)
- 백준 9012번
- 동적 프로그래밍(Dynamic Programming)
- 백준 10000번
- 그래프(Graph)
- 이분 탐색(Binary Search)
- 위상 정렬(Topological Sort)
- 백준 1707번
- 백준 2493번
- DFS
- 백준 21606번
- 백준 17608번
- 알고리즘 개념
- 이분 그래프(Bipartite Graph)
- 백준 2812번
- 위상 정렬(Topology Sort)
- 스택(Stack)
- 큐(Queue)
- 백준 2261번
- 백준 18352번
- 백준 2504번
- BFS(Breadth First Search)
- 트리(Tree)
- DFS(Depth First Search)
- 그리디 알고리즘(Greedy Algorithm)
- 다익스트라 알고리즘(Dijkstra Algorithm)
- 백준 1948번
- BFS
- 플로이드 워셜 알고리즘(Floyd-Warshall Algorithm)
- Today
- Total
Always Be Wise
나만의 무기를 갖기 : Authentication 본문
프로젝트 아이디어가 확정되고, 우리 서비스의 사용자 경험이 어떻게 이루어질지 정리한 후 API를 설계하였다.
이후, 서비스 주요 기능 구현을 위해 팀원들 각자가 공부를 시작하였고, 나 역시 해당 공부를 진행하면서 틈틈히 로그인과 회원가입 등
많은 서비스에서 필수적인 기본 기능에 대해서도 고민을 해보았다. 맨 처음 개발 공부를 시작했을 때에는 로그인, 회원가입 기능도
구현하는 것이 굉장히 어려웠었다. 사실 제대로 구현했다고 하기 힘들었다. 사용자 입력 값에 대한 유효성 검사도 제대로 하지 않았고,
아마도 보안상 문제도 많았을 것 같다. 기본 기능이라고는 하지만 서비스 사용을 위해서는 필수적인 것이고, 개인 정보를 다룬다는 점에서
아주 중요하기에 이전 보다는 발전된 방식으로 나아가야겠다는 생각이 들었다.
쿠키와 세션, JWT란?
HTTP는 비연결성(Connectionless)과 비상태성(Stateless)이라는 특징이 있다. 이는 서버의 자원을 절약하기 위해 모든 사용자의
요청마다 연결과 해제의 과정을 거치기 때문에 연결 상태가 유지되지 않고, 연결 해제 후에는 상태 정보가 저장되지 않는다.
그러나 이러한 특징으로 인해 사용자를 식별할 수 없어서 같은 사용자가 요청을 하더라도 매번 다른 사용자로 인식한다는 단점이 있다.
이러한 HTTP의 비연결성과 비상태성을 보완하는 것이 쿠키와 세션이다.
쿠키란 웹사이트에 접속할 때 생성되는 정보를 담은 임시 파일로, 서버가 사용자의 웹브라우저에 저장하는 데이터를 의미한다. 사용자는
서버에 요청할 때 쿠키를 함께 보내 서버가 사용자를 식별할 수 있게 해준다. 즉, 쿠키는 사용자가 가지고 있으면서 서버를 이용할 때마다
보여주는 것이라고 이해할 수 있다. 그런데 서버가 아닌 사용자에게 저장되기 때문에 임의로 고치거나 지울 수 있고, 누군가 가로채기도
쉬워 보안에 취약하다.
세션은 사용자 정보 파일을 서버 측에 저장하는 데이터를 의미한다. 서버에서는 사용자를 구분하기 위해 세션 ID를 부여하며 사용자는
이 세션 ID를 쿠키로 갖고 있다가 서버에 요청할 때 이를 인증 정보로 사용한다. 사용자에 대한 정보를 서버에 저장하기 때문에 쿠키보다
보안에 좋지만 사용자가 많아질수록 서버 메모리를 많이 차지하게 된다. 쿠키와 세션은 비슷한 역할을 하며 동작원리도 비슷하다.
그 이유는 세션도 결국 쿠키를 사용하기 때문이다.
쿠키와 세션의 가장 큰 차이점은 사용자의 정보가 저장되는 위치이다. 쿠키는 서버에 저장되지 안하 서버의 자원을 사용하지 않는 반면,
세션은 서버의 자원을 사용한다. 싸이클적 관점에서 쿠키도 유효 기간이 있지만 파일로 저장되기 때문에 브라우저를 종료해도 계속해서
정보가 남아 있을 수 있다. 반면 세션은 유효 기간을 지정할 수 있지만 브라우저가 종료되면 유효 기간에 상관없이 삭제된다. 속도면에서
쿠키의 경우 서버 요청 시 직접 정보를 가지고 요청하기 때문에 상대적으로 빠르다. 세션은 정보가 서버에 있기 때문에 추가적인 처리가
요구되어 상대적으로 느리다.
JWT는 Json Web Token의 약자로 인증에 필요한 정보들을 암호화시킨 토큰을 말한다. 세션 방식처럼 토큰 자체를 쿠키에 담아서
보내줄 수도 있고 HTTP 헤더에 담아서 보내줄 수도 있다. 동작 원리는 다음과 같다. 사용자가 로그인을 하면 서버에서 계정 정보를 읽어
해당 사용자를 확인 후 고유한 ID값을 부여한다. 그리고 기타 정보와 함께 내용(payload)에 넣는다. 그리고 토큰의 유효 기간을
설정하고 비밀 키를 이용하여 엑세스 토큰을 발급한다. 사용자는 서버로부터 엑세스 토큰을 받아 저장한 후 인증이 필요한 요청마다
토큰을 함께 보낸다. 서버는 해당 토큰의 서명부분을 비밀 키로 복호화한 후, 조작 여부 및 유효 기간을 확인한다. 검증이 완료되면 내용을
디코딩하여 사용자의 ID에 맞는 요청 데이터를 가져와 응답한다. JWT의 경우, 간편하고 확장성이 뛰어나다는 장점이 있지만 토큰을
탈취당할 경우 유효 기간이 만료되기 전까지 보안에 취약하다는 단점이 있다. 이를 위해 JWT의 유효 기간을 짧게 설정하는 경우가 있는데,
이 경우 사용자가 로그인을 자주하여 새로운 토큰을 발급 받아야 하는 불편함이 있다. 이를 개선하기 위해 리프레시 토큰을 사용할 수 있다.
리프레시 토큰은 처음에 로그인을 완료했을 때 엑세스 토큰과 동시에 발급된다. 그런데 리프레시 토큰은 상대적으로 긴 유효 기간을 가지며
엑세스 토큰이 만료되었을 때 새로 발급해주는 열쇠가 된다. 예를 들어, 리프레시 토큰의 유효 기간은 2주, 엑세스 토큰은 1시간이라 하자.
사용자가 엑세스 토큰을 1시간동안 사용하면 기존 엑세스 토큰은 만료된다. 이때 리프레스 토큰의 유효기간이 만료 전이라면 엑세스 토큰을
새롭게 발급받을 수 있다.
우리 프로젝트에서는?
우리 프로젝트에서는 JWT를 이용하기로 결정하였다. 그런데 JWT 생성 시 암호화 과정이 발생하는데 이 때, 해시 함수를 사용한다.
아래는 프로젝트에서 사용한 bcrypt라는 해시 함수에 대한 설명이다. 실행한 실험 결과에서 알 수 있듯이 Cost를 증가시킬 수록 해시를
처리하는 시간이 오래걸린다. 해시를 계산하는 것 역시 연산 작업이고 CPU를 사용하기 때문이다. 서버의 성능을 고려할 때, 적당한 수준의 Cost를 선정할 필요가 있었고 우리는 10을 선택하기로 하였다.
'카이스트 정글 - 프로젝트 > 나만의 무기를 갖기' 카테고리의 다른 글
나만의 무기를 갖기 : 도커(Docker) 개념 정리(2) (0) | 2022.02.24 |
---|---|
나만의 무기를 갖기 : 도커(Docker) 개념 정리(1) (0) | 2022.02.23 |
나만의 무기를 갖기 : API 설계 (0) | 2022.02.10 |
나만의 무기를 갖기 : 프로젝트 아이디어 (0) | 2022.02.09 |
나만의 무기를 갖기 : 프로젝트 아이디어(초안) (0) | 2022.01.21 |