Posts 쿠키 인증 vs 세션 vs JWT
Post
Cancel

쿠키 인증 vs 세션 vs JWT

쿠키

사용자가 로그인하면, 사용자 식별자를 암호화 또는 평문으로 쿠키에 담는 방식. 요청이 오면 쿠키에 담긴 식별자를 보고 유저를 구분한다.

  • 장점
    • 유효한 쿠키인지만 확인하면 되기에 서버자원과 비용을 아낄 수 있다.
    • 서버를 무상태(stateless)로 만들어줌.
    • 암호화를 하면 brute force 대응 가능(특정 횟수 이상 인증 실패시 ip 잠금)
    • 간단히 구현 가능
  • 단점
    • 쿠키가 탈취되면 위장 가능

세션

인증이 완료되면 사용자 식별자를 서버(DB 등)에 저장하고 그 저장한 곳에 접근하기 위한 해시 값을 세션 ID로 지정. 이후 세션 ID를 쿠키에 담아 보내주고, 사용자로부터 요청이 오면 세션id로 사용자 식별자를 가져온다.

  • 장점
    • 세션id가 노출되어도 유의미한 정보를 가지고 있지 않음.
    • 같은 유저가 다른 곳에서 로그인할 시, 누가 로그인 되어있는지 저장하고 있기에, 하나를 막을 수 있음.
  • 단점
    • 쿠키가 탈취되면 위장 가능
    • 요청이 많아지면 서버에 부하가 심해져, 세션 DB와 서버를 확장해야 한다.
    • 세션 관리 시스템에 문제가 생기면 시스템 전체에 문제가 생긴다.

JWT

인증이 되면, JWT 토큰(access token)을 클라이언트로 보내줌. 클라이언트는 헤더에 JWT를 적용하여 서버로 요청을 보내면 서버는 JWT을 디코딩하여 유저를 식별함.


쿠키/세션 다룰 때 주의점

  • httponly을 통해 XSS 공격 막기
  • secure 옵션을 통해 패킷 탈취에 대비
  • 식별자는 암호화하여, brute force 막기.
  • 특정 횟수 이상 인증 실패 시 ip 차단
  • CSRF 에 대비하기 위해 게시글에 html 입력 불가능하도록 하기.(sanitize)
  • 쿠키 탈취에 대비하기 위해 너무 동떨어진 위치에서 요청 시 차단
  • 암호화 시에는 레인보우 테이블 공격 방어로 salt를 섞고 한번 더 암호화하는 기법(bcrypt 등) 사용
  • 만료기간 설정 or 브라우저 닫을 시 만료

JWT 다룰 때 주의점

  • refresh token 탈취 시에 대응하기 위해, 같은 refresh token 사용이 두 번 감지되면 그 refresh token 이후 발급 된 모든 refresh token을 폐기
    • https://developer-ping9.tistory.com/239
    • 다만 이 경우에도 access token만 계속 탈취하거나, 공격자가 먼저 reissue 했을 땐, 감지 할 수 없다.
  • access token 만료 전에 reissue 시 탈취된 것으로 판단하여 access token을 폐기시킬 수 있음
    • 이 경우에도 access token 만료 후 리이슈해서 접근하면 감지할 수 없음.

쿠키 vs 세션

장단점만 보면 쿠키가 서버 확장에도 대응이 돼서 쿠키가 더 좋아보인다. 그런데 왜 사람들은 세션이 좋다고 하는 것일까? 로그인 상태를 저장하기에 동시 로그인 시 하나를 막을 수 있다지만, 서비스에 따라서는 동시로그인을 허용해야하는 경우가 많다. 정확히 어떤 차이점이 있을까?

Session ID in cookies vs. Encrypted cookie

  • 쿠키 암호화가 세션에 비해 단점인 것
    • 복잡한 암호화 알고리즘 필요, secret key 관리 필요, 비중앙화됨(동시로그인 못막음)
    • 신뢰할 수 있는 암호화 알고리즘을 사용해야함
    • 크기가 커서 네트워크 비용 발생 (바이트 수준 차이라 크게 문제는 안될듯)

글을 읽었을 때 게임과 같이 동시로그인을 꼭 막아야하는 경우가 아니면, 쿠키 암호화가 성능상/구현상 더 좋은 거 같음. 암호화 알고리즘도 라이브러리화 된 신뢰성 있는 것이 많기에 글에서 본 단점도 상쇄된다. secret key 관리만 개발자가 주의하면 될 거 같음.


물리적 해킹일 땐 어떻게?

ex) PC방에서 A유저가 로그인 하고 자리를 떴는데, B가 와서 그대로 사용할 경우

  • 쿠키 / 세션의 경우 : 만료기간 두기가 최선일 거 같음.
  • JWT : refresh token 사용 + refresh token 탈취 대비책은 위에서 “주의점”에 적은 대로.

네이버 로그인 방식

  • NID_AUT, NID_SES 사용
    • 링크에 나온대로 두 쿠키를 복사한 후 다른 브라우저에 넣어봤는데, 로그인이 되었다.
    • 그런데 다른 페이지로 이동하려니 로그인이 막힘. 다른 쿠키도 차례대로 넣어봤는데 동작하지 않음
  • 네이버에 접속하자마자 바로 JSESSIONID란 쿠키가 생성됨. 이름이나 값이 단순 숫자인것으로 보아 세션은 사용하는거 같은데, 로그인 후 새로 생기는 것들은 암호화 되어있고 기존 JSESSIONID와는 독립되어보임.
  • 서비스 형태, 위에서 나온 현상을 봤을때 SSO을 네이버에서도 사용하는 것 같음. 그런데 SSO를 어떤 방식으로 인증하는 걸까?
    • 찾기가 어려움..
    • 다만 쿠키를 봤을때, JWT는 사용하지 않는 것으로 보임. 그리고 SSO는 큰 규모의 서비스를 대상으로 하는데, 세션을 사용하면 성능에 한계가 있어보임. 그럼 쿠키/세션/JWT 중에 있다면, 쿠키를 암호화하여 사용하는 것으로 보이는데 구체적인 내부 방식은 모르겠음.
    • Redis를 사용하면 세션 성능 문제를 해결할 수 있지만, 그렇게까지 세션을 고집할 이유는 없어보임.
This post is licensed under CC BY 4.0 by the author.

프론트 아키텍쳐 흐름

서블릿 필터

Comments powered by Disqus.