210913 TIL - 세션/쿠키, JWT

ミンミン·2021년 9월 13일
0

TIL

목록 보기
3/42

인증

프론트엔드에서 '인증'은 로그인, 회원가입 등 도입부분에서 사용한다. 서버에 '인증'은 모든 api 요청에 대해 사용자를 확인하는 작업이다.
HTTP는 connetionless(클라이언트가 요청한 후 응답을 받으면 연결을 끊음), stateless(통신이 끝나면 상태를 유지하지 않음)을 가지고 있기 때문에 서버는 클라이언트가 누구인지 확인해야한다. 그래서 HTTP header에 인증 수단을 넣어 요청을 보낸다.

계정 정보를 요청 헤더에 넣는 방식

계정정보 자체를 헤더에 담는다. 인증을 테스트 할 때 빠르게 시도해 볼 수 있지만 당연히!! 보안에 취약하다. 그리고 요청이 올 때마다 서버는 전달받은 데이터로 해당 유저가 맞는지 검증해야 하므로 비효율적이다.

쿠키/ 세션 방식

쿠키와 세션은 서버의 세션과 사용자 쿠키를 기반으로 하는 인증 방식이다.

쿠키

  • 클라이언트 로컬에 저장하는 작은 데이터 파일
  • key = value 형태
  • 사용자에게 발급된 세션id를 저장
  • 사용자인증이 유효한 시간을 명시할 수 있으며 유효시간이 정해지면 브라우저가 종료되어도 인증이 유지된다. 장바구니, 24시간 동안 창 띄우지 않기 등에 사용
  • 쿠키는 사용자가 따로 요청하지 않아도 브라우저가 request시에 request header에 넣어서 자동으로 서버에 전송한다

세션

  • 서버에서 가지고 있는 정보
  • 서버에서는 클라이언트를 구분하기 위해 세션 ID를 부여하며, 서버에 접속해서 브라우저를 종료할 때까지 인증상태를 유지한다.
  • 세션 유효 시간을 설정할 수 있지만, 유효 시간 전이라도 브라우저가 꺼지면 세션도 만료된다
  • 쿠키보다 보안에 좋지만, 사용자가 많아지면 서버 메모리를 많이 차지한다

인증 순서

  1. 클라이언트가 로그인을 위해 정보를 서버에 전달한다
  2. 전달받은 정보로 회원 db와 비교해 사용자를 확인한다
  3. 로그인 성공시 사용자를 식별할 수 있는 고유한 세션 ID 를 생성해 세션 저장소(DB나 메모리, 보통 redis를 많이 사용한다)에 저장한다
  4. 세션ID를 응답에 담아보내면 클라이언트는 해당 값을 쿠키에 저장한다
  5. 이후 요청에는 헤더에 쿠키를 실어서 전달한다
  6. 서버는 쿠키를 받아 세션 저장소에 저장된 세션ID인지 확인하고, 유여한 쿠키일 경우 요청받은 데이터를 반환한다

장점과 단점

쿠키가 노출되어도 큰 문제가 없고, 요청을 주는 사용자마다 고유 세션ID가 있어 일일이 회원정보를 확인할 필요가 없다. 하지만 쿠키가 아닌 클라이언트 요청 자체를 탈취하면(하이재킹) 해커의 요청을 사용자로 인식하게 된다. (이를 방지하기 위해 세션의 유효시간을 짧게 하고, HTTPS를 사용해 보안성을 높인다). 그리고 세션ID를 모든 서버에서 이용할 수 있어하므로, 중앙 세션 저장소가 없으면 시스템 확장이 어렵다. 중앙 세션 저장소에 장애가 발생하면 인증 전체에 문제가 생길 수 있다.

JWT(Json Web Token)

JWT는 인증에 필요한 정보들을 암호화시킨 토큰을 의미한다. Access Token을 HTTP 헤더에 실어 서버로 보낸다. 쿠키/세션방식은 세션 저장소가 필요하기 때문에 메모리 과부하 문제가 생길 수 있지만, JWT 방식은 서버 리소스를 사용하지 않는다.

형식

  • Header : 정보를 암호화할 방식(alg), 타입(type) 등
  • Payload : 서버에서 보낼 데이터, 일반적으로 유저 고유 ID 값, 유효 기간이 들어간다. 쉽게 디코딩이 가능하므로 민감한 정보는 넣지않는다
  • Verify Signature : Base64 방식으로 인코딩한 Header, payload, SECRET KEY를 더해 만든다. SECRET KEY를 알지 못하면 복호화할 수 없다. SECRET KEY 관리를 잘해야함!

인증순서

  1. 사용자 로그인
  2. 서버에서 계정정보를 읽어 사용자를 확인한 후, 사용자의 고유한 ID 값을 부여하고 기타 정보와 함께 payload에 넣음
  3. JWT 토근 유효기간 설정
  4. 암호화할 SECRET KEY를 이용해 ACCESS TOKEN을 발급한다
  5. 사용자는 Access Token을 받아 저장한 후, 인증이 필요한 요청마다 토큰을 헤더에 실어 보낸다
  6. 서버에서는 해당 토큰의 Verify Signature를 SCRET KEY로 복호화한 후, 조작 여부, 유효 기간을 확인한다.
  7. 검증이 완료되면 payload를 디코딩하여 사용자의 Id에 맞는 데이터를 가져온다

장점과 단점

  • JWT는 발급한 후 검증만하면 되기 때문에 추가 저장소가 필요없다. 그래서 서버를 확장하거나 유지, 보수하는데 유리하다.
  • 토큰 기반으로 하는 다른 인증 시스템을 이용할 수 있다. (소셜 로그인 등)
  • 이미 발급된 JWT는 유효기간이 만료될 때까지 삭제가 불가능하다. 악의적으로 사용되어도 속수무책...이 때는 aceess token의 유효기간을 짧게 하고, refresh token이라는 새로운 토큰을 발급한다.
  • payload 정보가 제한적이다
  • JWT는 길이가 길어 인증이 필요한 요청이 많아질수록 서버의 자원 낭비가 발생한다
profile
같이 성장해 나가는 개발자가 되고 싶습니다

0개의 댓글