JWT TOKEN🍗Frontend/웹 관련 지식2022. 5. 23. 06:44
Table of Contents
등장 배경
기존 Cookie와 Session 기반(세션 기반)의 인증의 문제
- 기존 Cookie와 Session을 이용한 세션 기반 인증은 HTTP의 Stateless 프로토콜의 특징을 해결하기 위해 등장했다.
- 세션 기반 인증은 사용자의 인증 정보를 세션 형태로 서버 내에 저장하고 인증이 필요할 때마다 session-ID로 검증을 했다.
→ 매번 요청이 일어날 때마다 세션 저장소를 조회해서 session-ID를 검증해야 한다!
→ DB에 접근하는 로직이 한번 더 수행됨! - 가장 큰 단점은 서버에 메모리를 저장하기 때문에 서버가 클라이언트가 요청하는 데이터에 응답함과 동시에 사용자의 인증 정보도 관리해야 했다.
- 즉, 접속한 사용자가 증가하면 서버가 그만큼 과부하가 일어난다는 의미이다.
→ HTTP의 장점인 Stateless를 위배하고 Stateful의 성격을 지님 - 만약 세션 저장소에 문제가 발생하면 인증 체계가 무너진다.
→ 다른 인증된 유저도 인증을 할 수 없음 - session-ID가 탈취되었을 경우 클라이언트인 척하는 보안의 약점이 있을 수 있다!
세션 문제
- 유저가 인증할 때 서버에 해당 인증 내용을 저장하는 것을 세션이라고 한다.
- 만약 웹사이트에서 로그인하는 유저의 수가 늘어나면서 서버의 메모리에 이를 저장한다면 서버의 램이 과부화 될 것이고 DB를 사용해서 저장한다면 DB의 성능이 저하될 것이다!
확장성 문제
- 더 많은 트래픽을 감당하기 위해 여러대의 서버 컴퓨터를 추가하거나 여러개의 프로세스를 돌려야 한다.
- 세션을 사용하면서 분산된 시스템을 설계하는 것은 매우 어렵다!
- 만약 scale out을 하고 싶을 때 인증 정보를 저장해야 하는 세션 저장소가 scale out을 하기 이전의 서버에 있기 때문에 따로 session-ID를 저장해야 한다 ㅠㅠ
JWT TOKEN
What?
- JSON Web Token의 줄임말로, JSON 객체를 사용해 정보를 안정성 있게 전달하는 웹표준이다.
가볍고 자가수용적(Self-Contained) 방식으로 정보를 안정성 있게 전달해준다.
→ 자가 수용적?
→ JWT는 필요한 모든 정보를 자체적으로 지니고 있다.
→ JWT TOKEN은 토큰에 대한 정보, 전달해야 될 정보, 토큰이 검증되었다는 signature를 포함! - 클라이언트 측에서 토큰을 관리해야 하므로 브라우저에서 토큰을 저장해야 한다
장점
- 서버에서 상태를 저장하는 세션 기반 인증과 다르게 토큰 기반 인증은 서버에서 인증 정보를 저장하고 있지 않다.
→ 토큰 기반 인증은 세션 기반 인증과 다르게 토큰을 이용하여 인증을 하는 방식이다!
→ 토큰이 유효한 토큰인지 아닌지만 검증하면 되기 때문에 서버에 과부하를 일으키지 않는다!
→ 서버 확장성에 장점을 가진다. - Javascript, Python 등 주류 프로그래밍 언어에서 지원된다!
- JWT는 자가수용적인 성격을 지니므로 클라이언트와 서버 사이에서 쉽게 전달될 수 있다!
→ HTTP 헤더나 URL 파라미터로 전달하기 때문에 유저의 세션을 유지할 필요가 없고 가볍게 데이터를 주고 받을 수 있다. - 쿠키를 전달하지 않아도 되므로 쿠키를 사용해서 발생하는 취약점이 사라진다.
- REST 서비스 제공 가능
단점
- JWT의 Stateless한 성격 때문에 임의로 삭제할 수 없다
→ 만료 시간을 꼭 넣어주자 - 토큰이 탈취당하면 만료될 때까지 대처가 불가능하다 ㅠㅠ
→ JWT TOKEN의 stateless한 성격 때문이다..
→ JWT TOKEN을 발급해서 전달하면 클라이언트가 관리하기 때문! - 클라이언트 측에서 토큰을 관리해야 하므로 브라우저에서 토큰을 저장해야 한다
JWT Token 구조
- JSON Web Token의 줄임말로, JSON 객체를 사용해 정보를 안정성 있게 전달하는 웹표준!
- 예를 들어, 로그인한 사용자만 이용할 수 있는 웹페이지로 이동할 때, 회원임을 인증하는 토큰을 넘겨줘서 해당 웹페이지에 접근할 수 있도록 해준다!
- jwt token은 아래와 같이 header, payload, signature의 세 파트로 이루어져있다!
- header:
토큰의 유형과 HMAC, SHA256등 해시 암호화 알고리즘으로 구성되어 있다. - payload:
토큰에 담을 정보를 담고 있다! 정보는 key / value 쌍으로 이루어져 있다. 일반적으로 유저의 ID, 유효기간 등이 들어있다!- 만약 payload에 들어있는 유저의 ID를 확인하고 싶다면 secret key가 있어야 token을 디코딩 할 수 있다!
→ secret key가 있는 곳에서만 해독할 수 있음
- 만약 payload에 들어있는 유저의 ID를 확인하고 싶다면 secret key가 있어야 token을 디코딩 할 수 있다!
- signature:
header, payload의 값을 각각 Base64 방식으로 인코딩한 값과 header에 명시되어 있는 알고리즘과 secret key(서버만 알고 있는 암호)를 해싱한 후 다시 Base64 방식으로 인코딩하여 생성한다! - 생성된 토큰은 HTTP 통신을 할 때 Authorization이라는 key, value로 사용되며 value(jwt-token) 앞에 Bearer를 붙여서 사용한다!
{
"Authorization": "Bearer {JWT TOKEN}"
}
JWT Token 저장 위치
- 클라이언트가 토큰을 저장할 때, 쿠키, 웹 스토리지에 저장할 수 있다.
웹 스토리지(Session/Local)
- CSRF 공격에는 안전!
→ 자동으로 Request에 담기는 쿠키와 다르게 Javascript 코드에 의해 헤더에 담긴다! - XSS에 취약 ㅠㅠ
→ Local Storage에 접근하면 바로 토큰을 탈취할 수 있다
Cookie
- XSS 공격에 Local Storage보다 안전하다!
→ 쿠키의 httpOnly 옵션을 사용하면 Javascript 코드로 쿠키에 접근 자체가 불가능하다
→ XSS 공격으로 쿠키의 정보를 탈취할 수 없음! - 자동으로 request에 실리는 쿠키의 특성상 사용자의 컴퓨터에서 요청을 위조할 수 있다 ㅠㅠ
- CSRF 공격에 취약 ㅠㅠ
→ 쿠키는 자동으로 request에 담아서 보내기 때문에 공격자가 request url을 안다면 사용자가 관련 link를 클릭하도록 유도해서 request를 유도할 수 있음
가장 좋은 방법?
- refresh Token을 httpOnly 쿠키로 설정하고 URL이 새로고침 될 때마다 refresh 토큰을 request에 담아 응답으로 새로운 access Token을 발급 받아서 Javascript private variable에 저장하자!
→ refresh Token이 CSRF 공격을 받아도 공격자는 access Token을 알 수 없다
→ CSRF 요청을 위조하여 피해자가 의도하지 않은 서버 동작을 일으키는 공격이기 때문에 refresh Token을 통해 받아온 response에 담긴 access Token은 공격자가 확인할 수 없다 - 즉, 쿠키를 사용하여 XSS를 막고 refresh Token을 사용하여 CSRF를 막을 수 있다!!
'Frontend > 웹 관련 지식' 카테고리의 다른 글
SOP, CORS (0) | 2022.09.13 |
---|---|
Rest API / Rest-ful (0) | 2022.05.30 |
쿠키🍪와 세션/캐시 + 웹 스토리지 (0) | 2022.05.17 |
Proxy (Forward, Reverse) (0) | 2022.02.15 |
서버와 서버리스 (0) | 2021.08.22 |
@덕구공 :: Duck9s'
주니어 개발자에욤
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!