WEB # [HTTP와 쿠키방식과 세션방식 그리고 JWT의 장단점]

Danny·2023년 10월 11일
0

백엔드

목록 보기
2/10

인증과 인가에 대해서 알아보자
흐름에 맞게 HTTP부터 알아보도록 해본다.


HTTP

HTTP는 무상태성(stateless), 비 연결성(connectionless) 프로토콜로 누가 요청을 했는지, 인증된 클라이언트인지 확인할수 없다.

쿠키 방식

쿠키는 클라이언트에 저장되는 key와 value로 이루어진 데이터이다.
인증 유효 시간을 설정할 수 있고 유효 시간이 정해진다면 클라이언트가 종료되어도 쿠키가 유지된다.
서버와 요청 응답으로 인해 쿠키가 저장되면 다음 요청은 쿠키에 담긴 정보를 이용해 참조한다.
그러나 문제점으로 사용자 인증에 대한 정보를 모두 클라이언트가 가지고 있게되므로
http 요청을 탈취당할 경우 쿠키 자체를 탈취당해 사용자 정보를 모두 빼앗길 수 있다.
그래서 쿠키 자체는 보안과는 큰 상관이 없는 장바구니 혹은 자동로그인 설정 등에 이용할 수 있다고 한다.

세션 방식


세션은 쿠키를 기반으로 하지만 클라이언트에 저장하는 쿠키와는 다르게 서버에 저장하여 관리한다.
서버에서는 클라이언트를 구별하기 위해 각각의 세션ID를 클라이언트마다 부여하게되며 클라이언트가 종료되기 전까지 유지한다.
클라이언트에 저장하는 쿠키보다는 보안이 좋다.
세션 또한 문제점이 있는데 세션 하이재킹 공격이 가능하니 세션의 유효시간을 만들어 예방할 수 있다.
그리고 세션 저장소를 서버에서 관리하기 때문에 사용자가 많아지면 많아질수록 서버에 걸리는 부하가 증가한다.
동시 접속자가 많아지면 해결할 방법을 찾아야 될것이다.

JWT


토큰은 인증을 위해 사용되는 암호화 된 문자열을 말한다.
JWT는 Json Web Token의 약자이고 인증에 필요한 정보들을 암호화시킨 토큰을 말한다.
세션 방식처럼 토큰 자체를 쿠키에 담아서 보내줄 수도 있고 HTTP 헤더에 담아서 보내줄 수도 있다.

애플리케이션이 실행될 때, JWT를 static 변수와 로컬 스토리지에 저장하게 된다.
static 변수에 저장되는 이유는 HTTP 통신을 할 때마다 JWT를 HTTP 헤더에 담아서 보내야 하는데, 이를 로컬 스토리지에서 계속 불러오면 오버헤드가 발생하기 때문이다.
클라이언트에서 JWT를 포함해 요청을 보내면 서버는 허가된 JWT인지를 검사한다.
또한 로그아웃을 할 경우 로컬 스토리지에 저장된 JWT 데이터를 제거한다.
(실제 서비스의 경우에는 로그아웃 시, 사용했던 토큰을 blacklist라는 DB 테이블에 넣어 해당 토큰의 접근을 막는 작업을 해주어야 한다.)

토큰은 3가지 요소로 구성되어 있다.
Header: 3가지 요소를 암호화할 알고리즘 등과 같은 옵션이 들어간다.
Payload: 유저의 고유 ID 등 인증에 필요한 정보가 들어간다.
Verify Signature: Header, Payload와 Secret Key가 더해져 암호화된다.

Header.PayLoad.VerifySignature로 만들어진다.
Header와 Payload는 누구나 디코딩하여 내용을 확인할 수 있기때문에 유저의 비밀번호 같은 정보는 넣지 않도록 한다.
하지만 Secret Key를 알지 못하면 VerifySignature는 복호화할 수 없다.

그렇기 때문에 토큰을 변조하더라도 VerifySignature가 Payload를 기반으로 암호화 되었기 때문에 유효하지 않은 토큰으로
검증이 가능하다.

토큰은 일단 세션보다 훨씬 간편한다.
세션처럼 별도의 저장소 관리가 필요하지 않고 토큰을 발급 후 클라이언트에게 전송 후 검증하는 과정만 있으면 된다.
그러나 발급된 JWT는 삭제가 불가능하다.
세션 같은 경우에는 악의정으로 사용된다면 해당 세션을 삭제하면 된다.
토큰은 탈취당하게 되면 유효 시간이 종료되기 전까지는 탈취자가 얼마든지 악의적으로 사용이 가능하다.
그래서 Refresh Token이라는 것을 이용해 피해를 조금이라도 줄일 수 있다.

토큰 기반 인증 시스템의 이점

  • 무상태성(Stateless) & 확장성(Scalability)
    토큰은 클라이언트 측에 저장되기 때문에 서버는 완전히 Stateless하며, 클라이언트와 서버의 연결고리가 없기 때문에 확장하기에 매우 적합하다. 만약 사용자 정보가 서버 측 세션에 저장된 경우에 서버를 확장하여 분산처리 한다면, 해당 사용자는 처음 로그인 했었던 서버에만 요청을 받도록 설정을 해주어야 한다. 하지만 토큰을 사용한다면 어떠한 서버로 요청이 와도 상관이 없다.

  • 보안성
    클라이언트가 서버로 요청을 보낼 때 더 이상 쿠키를 전달하지 않으므로, 쿠키 사용에 의한 취약점이 사라지게 된다. 하지만 토큰 환경의 취약점이 존재할 수 있으므로 이에 대비해야 한다.

  • 확장성(Extensibility)
    시스템의 확장성을 의미하는 Scalability와 달리 Extensibility는 로그인 정보가 사용되는 분야의 확정을 의미한다. 토큰 기반의 인증 시스템에서는 토큰에 선택적인 권한만 부여하여 발급할 수 있으며 OAuth의 경우 Facebook, Google 등과 같은 소셜 계정을 이용하여 다른 웹서비스에서도 로그인을 할 수 있다.

  • 여러 플랫폼 및 도메인
    서버 기반 인증 시스템의 문제점 중 하나인 CORS를 해결할 수 있는데, 애플리케이션과 서비스의 규모가 커지면 여러 디바이스를 호환시키고 더 많은 종류의 서비스를 제공하게 된다. 토큰을 사용한다면 어떤 디바이스, 어떤 도메인에서도 토큰의 유효성 검사를 진행한 후에 요청을 처리할 수 있다. 이런 구조를 통해 assests 파일(Image, html, css, js 등)은 모두 CDN에서 제공하고, 서버 측에서는 API만 다루도록 설게할 수 있다.

JWT 단점 및 고려사항

  • Self-contained:
    토큰 자체에 정보를 담고 있으므로 양날의 검이 될 수 있다.
    토큰 길이: 토큰의 페이로드(Payload)에 3종류의 클레임을 저장하기 때문에, 정보가 많아질수록 토큰의 길이가 늘어나 네트워크에 부하를 줄 수 있다.

  • Payload 인코딩
    페이로드(Payload) 자체는 암호화 된 것이 아니라, BASE64로 인코딩 된 것이다. 중간에 Payload를 탈취하여 디코딩하면 데이터를 볼 수 있으므로, JWE로 암호화하거나 Payload에 중요 데이터를 넣지 않아야 한다.

  • Stateless
    JWT는 상태를 저장하지 않기 때문에 한번 만들어지면 제어가 불가능하다. 즉, 토큰을 임의로 삭제하는 것이 불가능하므로 토큰 만료 시간을 꼭 넣어주어야 한다.

  • Tore Token
    토큰은 클라이언트 측에서 관리해야 하기 때문에, 토큰을 저장해야 한다.

https://yeonyeon.tistory.com/264
https://minhan2.tistory.com/69

0개의 댓글