일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 프로그래머스 데브코스 프론트엔드
- 이벤트 수식어
- 다른컴퓨터에서 git사용
- netlify redirect
- 프로그래머스 K_Digital Training
- vue 지역 컴포넌트
- vue mixin
- 폼 입력 바인딩
- 리스트 렌더링
- SCSS forward
- 프로그래머스 프론트엔드 데브코스
- SCSS extend
- vue 이벤트 수신
- 리액트
- react next
- KDT 프로그래머스
- 고양이 사진 검색기
- git 같은계정 다른 컴퓨터
- postcss
- SCSS import
- SCSS use
- 쌓임맥락
- intersection opserver
- KDT 프로그래머스 데브코스 프론트엔드
- flex
- nextjs사용법
- Spacer
- Vue
- vuex map
- 프로그래머스 데브코스
- Today
- Total
혼자 적어보는 노트
JWT에 대해 이해하기 (+ cookie, session) 본문
이전 프로젝트에서 JWT토큰을 사용한 방식으로 로그인을 구현했었는데 주는대로 사용만 했지 JWT토큰에 제대로 알고있지 못하다고 생각하여 cookie와 session과 함께 간단하게 정리해보기로 했다.
Cookie
쿠키는 클라이언트가 웹사이트에 접속할 때 그 사이트가 사용하게 되는 일련의 작은 기록 파일과 같다.
쿠키는 서버가 클라이언트에 정보를 전달 할 때 저장하려는 정보를 응답 헤더에 저장하여 전달하고
key-value 형태의 문자열 형태로 저장하게 된다.
쿠키를 로그인에 사용하면 set-cookie로 반환받은 쿠키값(id,password)을 토대로 인증이 필요한 요청을 할 때마다 다시 쿠키와 함께 요청을 하여 사용자가 일일이 id/password를 입력해야하는 번거로움을 줄일 수 있었다.
하지만 이렇게 쿠키만을 통해 로그인을 인증하게 되면 id, password에 대한 정보까지 노출이 되어서 보안에 좋지 않고, 조작된 데이터가 넘어갔을 때 방지를 할 수가 없다.
Cookie + Session의 조합
개인의 정보를 그대로 노출했을 때의 단점을 보완하기 위해 나온 것이 Session이다.
저장된 정보를 주고받는 것에 있어서는 Cookie방식과 비슷하지만 민감한 정보인 id/password를 그대로 주고받는 방식이 아닌 인증 정보 자체는 session 저장소에 저장하고 session ID를 쿠키에 담아 클라이언트에게 전달하는 방식이다.
자물쇠, 열쇠와 비슷한 개념인데 공개되어도 상관없는 key(session ID) 를 클라이언트에게 전달하고 인증이 필요한 요청을 할 때 열쇠를 사용하여 서버에 있는 자물쇠를 여는 방식이다. 그렇기 때문에 중간에 key를 탈취당해도 id와 password 정보를 알 수 없어 cookie만을 사용했을 때보다 안전하다.
인증 과정
1. 사용자가 로그인을 하면 서버에서 유니크한 session ID를 생성하고 Session Storage에 저장을 한다.
2. session ID를 cookie나 json 형태로 클라이언트에게 반환한다.
3. 클라이언트는 이후 인증 요청 시 Session ID를 쿠키에 함께 담아 전달한다.
4. 서버는 cookie로 받은 session ID가 Session Storage에 있는 지 조회하고 있다면 인증이 확인되어 필요한 데이터를 넘겨준다.
보안에 문제가 발생하여 누군가 세션 ID를 탈취할 경우 서버의 Session Storage에서 해당 세션 ID를 삭제해버리면 더이상 그 세션 ID로 인증을 할 수가 없고, 반대로 session storage에 문제가 생긴다면 사용자 측에서 인증을 사용할 수 없다.
Session의 단점
1. 세션 저장소가 필수적으로 존재해야 한다.
아무래도 서버에서 session ID라는 데이터를 보관하고 있어야 하기 때문에 보관에 대한 비용이 발생하고 사용자가 많아질 수록 메모리를 많이 차지하게 된다. 또한 세션 저장소에 문제가 생긴다면 사용자 측에서 인증을 사용할 수 없다.
2. 서버를 추가할 때 걸림돌이 된다.
그리고 서버를 여러개로 늘릴 경우 각 서버마다 세션 ID를 저장해주어야한다. 예를들어 서버1을 사용하고 있고 이 곳에서 세션 정보들을 저장하였는데 추가된 서버2에는 이전의 세션 정보들이 없기 때문에 이부분을 보완하기 위해 중앙 세션 저장소가 있어야 한다.
3. 인증을 하기 위해 세션 저장소를 매번 조회해야 한다.
JWT 방식
session방식의 단점을 보완하기 위해 나타난 암호화된 웹 토큰 방식이다.
Header, Payload, Signature 이렇게 세가지의 구성요소가 있으며 점(.)으로 구분되어있다.
Header
{
"typ": "JWT",
"alg": "HS256"
}
header에는 토큰의 타입, 서명을 생성할 때 어떠한 알고리즘이 사용되었는지를 표기한다.
Payload
{
"sub": "1234567890",
"name": "Jay",
"iat": 2314224
}
payload에는 claim이라는 정보를 저장하는데, 사용자 혹은 토큰에 대한 정보를 저장한다.
여기서 중요한 점은 payload에는 민감한 개인 정보를 저장하지 않아야 한다.
header와 payload에는 암호화가 되어있지 않기 때문에 누구나 디코딩을 하면 값을 알 수 있기 때문이다.
=> JWT는 단순히 식별을 하기위한 정보를 담는 것
Signature
Header와 Payload를 디코딩한 값을 서버가 가지고 있는 개인키를 사용하여 암호화를 시킨 값이다.
Signature는 서버에 있는 개인키만을 가지고 복호화를 할 수 있다.
즉, 이 서명된 값을 서버의 개인키로 복호화하여 header와 payload의 값과 일치하는지 확인하여 인증을 해주는 방식이기 때문에 header나 payload가 클라이언트에 의해 변경될 경우 인증이 무효화된다.
JWT의 장점
1. 인증 정보에 대한 별도의 저장소가 필요없다..
2. 클라이언트의 상태를 서버가 저장하지 않아도 된다. (stateless)
3. 토큰 기반으로 다른 로그인 시스템에 접근 및 권한 공유가 가능하다.
JWT의 단점
1. 토큰이 탈취된다면 만료될 때까지 대처가 불가능하다
세션의 경우 누군가가 세션을 탈취했을 때 서버에서 세션 ID를 삭제하여 추가적으로 인증하는 것을 막을 수 있지만
JWT방식의 경우 상태를 저장하고 있지 않기 때문에 토큰이 만료될 때까지 막을 방도가 없다.
2. 많은 데이터 전달으로 부하가 생길 수 있다.
또한 base64방식의 인코딩을 통한 정보를 전달하기 때문에 claim에 넣는 데이터가 많아질 경우 토큰 길이가 길어지고 네트워크 전달 시 많은 데이터를 전달하게 되어 부하가 생길 수 있다.
3. payload에는 민감한 정보를 저장할 수 없다.
Access Token/Refresh Token
JWT 방식의 치명적인 단점인 1번을 보완하기 위해 JWT를 처음 발급 할 때 Access Token과 Refresh Token을 발급하는 방법이 있다.
Access토큰은 짧은 만료시간을 가지고 Refresh 토큰은 비교적 긴 시간의 만료시간을 두어 인증 요청을 할 때 Access token으로 요청을 하고 Access Token이 만료되었을 때 Refresh Token을 사용하여 서버에게 새로운 Access Token을 발급받는 방식이다.
이 방식을 사용한다면 Refresh Token을 저장하기위한 Storage가 필요하다. 토큰이 탈취되었다고 판단이 되면 Refresh Token의 Storage를 초기화하여 탈취된 토큰이 Refresh를 더이상 하지 못하도록 막을 수 있다.
어찌보면 세션과 비슷하게 사용된다고 생각할 수 있지만 세션은 요청이 들어올 때마다 매번 세션 ID를 저장소에서 조회를 해야 하지만 Refrash는 AccessToken이 만료되었을 때만 비교를 하기 때문에 조회 횟수 차이가 크다.
Reference
https://velog.io/@jinyoungchoi95/JWTJson-Web-Token-%EC%9D%B8%EC%A6%9D%EB%B0%A9%EC%8B%9D
'기타' 카테고리의 다른 글
ngrok으로 로컬 개발 환경 외부에 공유하기 (0) | 2022.11.10 |
---|---|
객체지향 프로그래밍(OOP) (0) | 2022.09.16 |
정규 표현식 공백 및 특수문자 체크 (0) | 2022.09.04 |
프로그래머스 데브코스 TIL - Day 52 (0) | 2022.05.31 |
[VSCode] 새 파일, 새 폴더 단축키 설정 (0) | 2022.05.31 |