스터디 주제로 JWT에 대해 공부하기로 하였다.
JWT를 먼저 공부하기 전에 먼저
인증/인가, 쿠키, 세션, 토큰에 대해 공부한 후 JWT에 대해 소개하도록 하겠다.
HTTP의 특징 (비연결지향, 상태없음)
로그인을 했지만, 문제점이 발생
예) 글을 쓸때 사용자가 로그인을 함, 글을 다 쓴다음에 수정을 하고 싶으면 인증을 한번 더 해야 함
사용자 입장에서 편리하지만, 해킹에 위험
세션 통신 절차
1. 인증이 완료된 클라이언트가 서버에 Resource를 요청합니다.
2. 서버에서는 HTTP Request를 통해 쿠키에서 Session id를 확인을 한 후에 없으면 Set-Cookie를 통해 새로 발행한 Session-id 보냅니다.
3. 클라이언트는 HTTP Request 헤더에 Session id를 포함하여 원하는 Resource를 요청을 합니다.
4. 서버는 Session id를 통해 해당 세션을 찾아 클라이언트 상태 정보를 유지하며 적절한 응답을 합니다.
쿠키보다 안전
예)
서버 모두 자체적으로 세션을 관리하고 있어서 생긴 문제
세션 스토리지로 해결 가능
- 그 중에 JSON WEB TOKEN을 사용한다.
JWT는 JSON Web Token의 약자로 전자 서명 된 URL-safe (URL로 이용할 수 있는 문자만 구성된)의 JSON이다. 전자 서명은 JSON 의 변조를 체크할 수 있게 되어 있다.
JWT는 HMAC 알고리즘을 사용하여 비밀키 또는 RSA를 이용한 Public Key/ Private Key 쌍으로 서명할 수 있다.
JWT는 세 파트로 나누어지며 . 을 통해 구분되며, 순서대로 Header, Payload, Signature로 구성된다.
1. Header는 토큰의 타입과 해시 암호화 알고리즘으로 구성되어 있다.
첫 째는 토큰의 유형 (JWT)을 나타내고
두 번째는 HMAC, SHA256 또는 RSA와 같은 해시 알고리즘을 나타내는 부분이다.
2. Payload는 토큰에 담을 클레임(claim) 정보를 포함하고 있다.
Payload에 담는 정보의 한 ‘조각’을 클레임이라고 부르고
이는 name / value의 한 쌍(JSON 형식)으로 이뤄져 있다.
토큰에는 여러 개의 클레임 들을 넣을 수 있다.
클레임의 정보는 등록된 (registered) 클레임, 공개 (public) 클레임, 비공개 (private) 클레임으로 세 종류가 있다.
access token과 refresh token 모두 사용자가 로그인을 하고 인증됐을 경우 서버에서 Secret Key를 사용해서 발급하는 토큰이다.
access token
글자 그대로 사용자가 서버에 request를 보낼 때 header에 함께 보내는 접근용 토큰
만료 기간을 10~15분으로 짧게 두어 자주 발급받게 한다.
이로써, 만약 access token이 다른 사람에게 도난당하더라도 금방 만료되어 안정성이 유지된다.
refresh token
access token이 만료됐을 때 access token을 재발급받기 위한 인증용 토큰이다.
평소의 요청에는 request에 포함되지 않으면 오직 access token을 재발급받는 용도로만 사용한다.
만료 기간은 자동 로그인 기능을 몇 달로 지정할 것인 가에 따라 조절하면 되고, 만료 기간이 끝나면 사용자에게 로그인을 다시 요청하면 된다.
token 생성 과정
사용자가 로그인 요청을 보내고, 보내온 요청에 따라 시크릿키를 통해서 토큰을 생성한다.
이때 서버는 access token 과 refresh token을 생성
서버는 access token은 저장하지 않고 refresh token만 따로 저장소에 저장
두 토큰을 클라이언트에 전달
access token이 만료가 되면, 브라우저에서는 access token과 refresh token을 함께 서버에 전달하게 됨
서버는 돌아온 refresh token을 확인하여 token 갱신하게 됨
사용자가 로그인을 요청하고 id, pw 정보가 유효하다면
서버에서 Secret Key를 사용해서 JWT(access token, refresh token)을 발급한다.
서버에서 JWT를 브라우저로 전달한다. 이때, 사용자의 local storage에 JWT(access token, refresh token)를 저장한다.
브라우저는 모든 request의 Authorization 헤더에 access token을 함께 전송한다.
서버는 브라우저가 보낸 access token을 식별하고 유효하다면, 원하는 응답을 제공해준다.
서버를 확장하는 데에 부담이 적다.
토큰으로 상태관리를 하기에 따로 세션을 둘 필요가 없다. (속도가 빠름)
하지만 토큰 관리를 해야한다.(토큰을 강제로 만료시킬 수 없다.) 결국 토큰도 탈취당할 수 있다 (보안에 신경을 써야 함, 유효기간을 짧게)
인증/인가를 위해 여러 가지 기술 쿠키, 세션, 토큰을 사용한다.
각각의 장점이 존재한다고 생각하고, 역시 보안이 가장 중요하다고 생각한다.
사용자 중심적으로 가용성을 더 향상시킬 것인가?
아니면 보안을 위해 보안성을 높일 것인가?
제공하는 서비스의 종류에 따라 중요도가 있을 것이다.
https://nesoy.github.io/articles/2017-03/Session-Cookie
https://nesoy.github.io/articles/2018-06/Load-Balancer
https://docs.microsoft.com/ko-kr/aspnet/web-api/overview/advanced/http-cookies
https://meetup.toast.com/posts/239
https://losikov.medium.com/part-6-authentication-with-jwt-json-web-token-ec78459b9c88
https://www.youtube.com/watch?v=y0xMXlOAfss
https://www.youtube.com/watch?v=TXWUNePimAc
https://www.youtube.com/watch?v=JZgD8aPkHSc