JWT 토큰이란??

Ko Seoyoung·2021년 7월 24일
3
post-thumbnail

Authentication (인증) vs Authorization (인가)

  • Authentication(인증): == 로그인, 아이디와 패스워드 등을 통해 특정 서비스에 일정권한이 주어진 사용자임을 인증을 받는 것.
  • Authorization (인가): 사용자가 한번 인증을 받은 후에 그 사용자가 특정 리소스에 액세스할 수 있는지 여부를 결정하는 프로세스이다.
    즉 네이버에 로그인으로 인증을 한 후 블로그에 글을 쓰거나 댓글을 다는 등 내 계정으로 '만' 할 수 있는 활동을 시도할 때, 네이버가 나의 로그인 여부를 보고 허가 해주는 것

매번 로그인 해주면 되지, 인가가 왜 필요한가??
1. 로그인은 꽤 무거운 작업이다. db에 저장된 사용자 계정의 해시값 등을 꺼내온 다음, 이것들이 사용자의 암호를 복잡한 알고리즘으로 계산한 값과 일치하는지 확인하는 과정 등을 거쳐야하기 때문이다.
2. 또한, 매 요청마다 아이디와 패스워드가 전송되는 것도 보안상 위험하다.


Session vs JWT

세션과 JWT는 인증보다 '인가'에 연관된 기술이다.

Session (세션)

전통적으로 많이 사용되어 온 방식으로, 서버 기반 인증방법이다.
세션 id를 사용해서 어떤 사용자가 서버에 로그인 되어있음이 지속되는 상태를 '세션'이라고 한다.

어떻게 인가를 하는가?

  1. 사용자가 로그인에 성공하면 세션을 발행한다.
  2. 그 세션을 브라우저에도 저장하고 (ex) 크롬에 session id로 쿠키 설정), 서버 메모리에도 저장한다.
    (경우에 따라 하드디스크와 데이터베이스 등에 저장)
  3. 인가가 필요한 요청을 보낼 때 서버에 세션값을 같이 보냄
  4. 서버는 메모리에 저장된 값과 세션값을 비교해서 맞는 값이 있으면 authorization

단점은?

  • 세션이 서버에 저장되어있기 때문에 사용자가 동시 다중 접속할 때 메모리가 부족해진다.
  • 서버가 재부팅되어야하는 상황이 오면 서버의 메모리에 저장된 세션이 모두 날아가고, 모든 사용자가 로그인이 튕겨서 다시 로그인해야 한다. (DB에 넣어둔 경우, 속도가 느려짐.)
  • 확장성면에서 분산된 서버의 경우 세션 유지가 제대로 안되기 때문에 서버 확장이 어렵다. (불가능하진 않지만 복잡해짐)

JWT (JSON Web Token)

사용자가 로그인을 하면 토큰을 주는데, 이 토큰을 서버가 기억하고 있지 않는다.
(시간에 따라 바뀌는 어떤 상태값을 안 갖는 것 - stateless, 반대로 세션은 stateful)

  • JWT Token 예: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

암호화된 3가지 데이터를 이어붙인 형태(aaa.bbb.ccc)로 구성되어 있다.
1. 헤더: 알고리즘(3번 서명 값을 만드는데 사용될 알고리즘이 지정 ex) HS256), type이 들어감 (언제나 JWT)
2. 페이로드: 토큰이 갖는 데이터
3. 서명 (signature): 1번 헤더에 정의된 알고리즘을 통해 암호화한 비밀 값으로 서버만 알고 있음

왜 세션을 대체하지는 못하는 것일까?

JWT는 세션처럼 모든 사용자들의 상태를 기억하고 있지 않다. 따라서 기억하는 대상들의 상태를 언제든 제어할 수 있지 않음!
예를 들어, 세션을 이용한 경우 한 기기에서만 로그인 가능한 서비스를 만들고 싶을 때, pc에서 로그인하면 핸드폰에서의 세션값은 사용못하게 하는 등 제어할 수 있음. 반면 JWT는 이미 줘버린 토큰을 뺏을 수 도 없음. 해커에게 토큰을 배앗겨도 토큰을 무효화할 방법도 없음.

해결방법?? 로그인시 accessToken, refreshToken 두 개의 토큰을 준다.

  • accessToken: 매번 인가를 받을 때 사용하는 토큰. (보통 수명이 짧음)
  • refreshToken: accessToken의 수명이 다했을 때 accessToken을 재발행 받기 위한 토큰 보통 2주정도 기간이 길게 잡힘
    (누군가를 로그아웃시키려면 refeshToken을 db에서 지워버리면 되는데 그래도 accessToken의 수명 동안은 바로 차단할 방법은 없음)

참고자료

profile
Web Frontend Developer 👩🏻‍💻 #React #Nextjs #ApolloClient

0개의 댓글