세션? 토큰? JWT?

‍김다솔·2021년 7월 9일
0

1. 인증 Autehntication

  • 로그인
  • 특정 사이트에 가입된 회원임을, 일정 권한이 주어진 사용자임을 인증

2. 인가 Authorization

  • 로그인이 유지된 상태에서 일어나는 일
  • 인증 받은 사용자가 이후 서비스의 여러 기능을 사용할 때
  • 자기 계정으로만 할 수 있는 활동을 시도할 때 로그인 되어있음을 알아보고 허가

사용자가 로그인한 사실을 서버가 인지할 수 있도록 하는 방법은?

  • 서버는 각 요청이 들어올 때마다, 요청을 보낸 사용자가 인증 과정을 거친 상태인지 확인해서 서비스 기능을 허용 해줄지 말지 결정해서 응답
  • DB에 저장된 사용자 계정의 Hash 값을 꺼내온 다음에 사용자 암호를 복잡한 알고리즘으로 계산한 값과 일치하는지 확인하는 과정을 거쳐야 해서 무거움

세션

  • 전통적으로 많이 사용됨
  • 로그인 성공 시 서버는 세션(영화관 티켓)을 출력하고, 이를 찢어서 반은 사용자의 브라우저로 보내고, 다른 반은 메모리에 올려 놓는다.
  • 경우에 따라 하드디스크나 DB에 넣기도 한다.
  • 브라우저는 티켓을 Session ID라는 이름의 쿠키로 저장하여 사이트에 요청을 보낼 때마다 실어 보낸다.
  • 서버에 로그인 되어있는 상태를 세션이라고 한다.
  • 서버가 재부팅되어야 하는 상황이 오면 메모리에 있는 것들이 다 날아가게 되는 문제점이 있다.
  • RedisMemCached같은 메모리형 DB 서버에 올려두기도 한다.
  • 서버가 복잡한 구성과 환경에서 어떤 상태를 기억해야 하므로 설계하기 어렵다.

JWT

  • 세션의 문제점을 보완하고자 토큰 방식인 JWT 고안
  • XML처럼 데이터 담을 때 쓰는 JSON의 Web Token
  • 로그인 하면 서버는 토큰이라는 표를 출력해서 건제주는데 이번엔 찢어서 주지 않고 그대로 준다. (서버가 무언가를 기억할 필요 없다.)
  • 인코딩 또는 암호화된 3가지 데이터를 이어 붙인다.
  • 잘 보면 중간에 점, 마침표가 두 군데 들어가 3개의 구간으로 나뉜다.
  • https://jwt.io/
  • 각각 header, payload, verify signature로 구분된다.

Payload

  • Claim : 토근에 담긴 사용자 정보 등의 데이터
  • payload에서 Base64로 디코딩해보면 JSON 형식으로 여러 정보들이 들어가 있다. 누가 누구에게 발급했는지, 언제까지 유효한지, 서비스가 사용자에게 이 토큰을 통해 공개하기 원하는 내용(사용자 닉네임, 관리자 여부 등)
  • 토큰에 이런 정보들이 들어가 있어서 서버가 요청마다 일일이 DB를 뒤져봐야할 것들이 줄어든다.
  • 토큰을 디코딩해서 임의로 조작할 수 있는 문제점이 존재한다.
  • 디코딩하면 type은 항상 고정값 JWT이 들어간다. 다른 하나인 alg(알고리즘 약자)은 Verify signature 값을 만드는데 사용될 알고리즘이 지정된다. H256 등 여러 암호화 방식 중 하나를 지정할 수 있다.
  • 헤더와 페이로드, 그리고 서버에 감춰놓은 비밀 값 이 3가지를 이 암호화 알고리즘에 넣고 돌리면 서명값이 나오는 것이다.
  • 서버는 요청에 토큰값이 실려오면 헤더와 페이로드의 값을 서버의 비밀 키와 함께 돌려봐서 계산된 값이 서명값과 일치하는지 확인한다.
  • 이처럼 시간에 따라 바뀌는 어떤 상태값을 갖지 않는 것을 stateless라고 하는데, session은 반대로 stateful하다.

결론

  • JWT가 세션을 대체하기에는 큰 결점이 있다.
  • 세션처럼 stateful해서 모든 사용자들의 상태를 기억하고 있다는 건 구현하기 부담되고 고려사항이 많지만, 되기만 하면 기억하는 대상의 상태들을 언제든 제어할 수 있다는 것을 의미한다.
  • 한 기기에서만 로그인 가능한 서비스를 만드려는 경우, PC에서 로그인항 상태의 사용자가 스마트폰에서 또 로그인하면 PC에서는 로그아웃되도록 기존 세션을 종료할 수 있다.
  • JWT는 편하긴 한데 통제는 못하기 때문에 토큰을 무효화할 방법이 없다. 이를 보완하고자 만료시간을 가깝게 잡아서 토큰의 수명을 아주 짧게 해준다.
  • 로그인 하면 토큰을 2개 주는데 수명이 짧은 access 토큰과 보통 2주 정도로 잡혀 있는 refresh 토큰이 있다.
  • 위 둘을 발급하고 클라이언트에게 보내고 나서 refresh 토큰은 사응값을 DB에 저장한다. 따라서 사용자는 access 토큰의 수명이 다하면 refresh 토큰을 보내는데 서버는 이를 DB에 저장된 값과 대조해보고 맞다면 새로운 access 토큰을 발급해주는 형식이다.
  • refresh 토큰만 안전하게 관리된다면 access 토큰이 만료될 때마다 다시 로그인할 필요 없이 새로 발급 받을 수 있게 된다.
profile
💻🎧⚽

0개의 댓글