[Web] Session Vs. Token (JWT)

DaeHoon·2022년 6월 17일
0

인증, 인가 (Authentication, Authorization)

  • 인증 (Authentication) : 쉽게 말하면 로그인, 클라이언트가 특정 서비스에 일정 권한이 주어졌는지 아이디와 패스워드를 통해 인증을 받는 것

  • 인가 (Authorization) : 서비스에서 사용자가 인증을 받았을 때만 할 수 있는 활동을 시도할 때 인증 유무를 통해 허가해 주는 것 (ex. 페이스북에서 내 친구 타임라인에 글을 올리는 행동)

Session Vs. Token (JWT)

1. Session

  • 사용자가 로그인에 성공하면 서버는 저장소에 key/value로 메모리에 저장한 뒤 브라우저에서는 key 값(sessionId)을 브라우저로 보낸다. 브라우저는 이 key 값을 쿠키로 저장한다.
  • 이 후 브라우저는 요청을 보낼 때마다 이 쿠키를 보내고 서버는 이 쿠키를 통해 특정한 서비스에 대한 인가를 함.
  • Stateful
  • Sesison Id를 통해 서버에 로그인이 되어있음이 지속되는 이 상태를 Session이라고 한다.

Session의 취약점

  • 서버가 꺼져버릴 경우 메모리에 있는 세션이 날아간다. -> 세션에 있었던 멤버들이 전부 로그아웃이 되어 다시 로그인을 해야한다.
  • 서버를 여러 대를 둘 경우 구현이 까다로움. (ex. 1번 서버에서 로그인, 3번 서버에서 인가가 필요한 서비스를 받는 경우에 3번 서버에는 사용자의 정보가 세션에 저장되어 있지 않음.)
  • 공용 db 또는 레디스 MemCached 같은 메모리형 데이터베이스 서버에 세션을 저장하는 방법으로 어느 정도 해결되나, 이 역시 1번과 같은 이슈를 가지고 있음.

2. JWT

  • header, payload, signature 3개로 나뉘어 있음.
  • header: Base64로 디코딩 해보면 type, alg라는 2개의 값 존재. type은 jwt 고정, alg는 3번 서명 값을 만드는데 필요한 알고리즘(HS256 등)이 지정 되있다. header, payload, 그리고 서버에 감춰놓은 비밀 값 이 셋을 이 암호화 알고리즘에 넣고 돌리면 signature가 나온다.
  • payload: Base64로 디코딩 해보면 Json 형식으로 정보들이 들어있다. (누가 누구에게 발급, 유효 기간, 사용자의 닉네임, 서비스 레벨, 관리자 등 이 토큰에 담긴 사용자 정보 등의 데이터를 Claim이라고 한다.)
  • signature: 인증된 사용자인지 판별하는 값. 브라우저의 signature 값과 서버에서 header, payload, 그리고 서버에 감춰놓은 비밀 값을 암호화 알고리즘에 넣어 나온 값이 일치하면 사용자에게 서비스를 인가해준다.
  • Stateless

JWT 토큰

  • Encoded

  • Decoded

Jwt 인증 로직

  • 사용자가 로그인에 성공하면 서버는 토큰을 브라우저에 준다.
  • 브라우저가 인가가 필요한 서비스에 접근할 때, 서버에 받은 jwt를 보낸다.
  • 서버는 jwt의 header, payload 그리고 서버 내의 비밀 값을 암호화 알고리즘에 넣어 받은 signature와 같은지 확인하고 유효 기간도 지나지 않았으면 로그인 된 회원으로 간주하고 인가를 해준다.

JWT 취약점

  • Stateless한게 단점. jwt의 토큰의 정보를 서버에 저장하지 않으므로, 누군가 이 토큰을 탈취한 경우에 토큰을 무효화 할 방법이 없음.
  • 예를 들면 PC에서 로그인한 사용자가 모바일로 또 로그인을 하면기존 로그인을 해제하고 로그인 하겠냐는 알림이 뜨지만 jwt에서는 이 방식이 어렵다.

완벽하지 않은 해결 방법

  • 유효 기간이 짧은 access 토큰, 유효 기간이 긴 refresh 토큰을 브라우저에 보내고 refresh 토큰의 값을 DB에 저장한다.
  • 브라우저의 access 토큰의 수명이 다할 시 브라우저는 refresh 토큰을 서버에 보내고, 서버는 보낸 토큰이 저장된 refresh 토큰과 일치하는지 확인하여 맞다면 새 access 토큰을 보낸다.
  • refresh 토큰만 안전하게 관리되면 access 토큰이 만료될 때마다 다시 로그인을 할 필요가 없음. 또한 중간에 access 토큰이 탈취되어도 refresh 토큰을 DB에서 지워 토큰 갱신을 안되게 할 수 있다. 하지만 그 짧은 시간에는 Jwt의 취약점과 동일한 상황이 발생할 수 있다.

참고 : https://www.youtube.com/watch?v=1QiOXWEbqYQ&t=777s

profile
평범한 백엔드 개발자

0개의 댓글