🌿SPRING/🍀공부 [SPRING]

[SPRING] Spring Security - 쿠키 vs 세션 vs JWT + Token

디카페인라떼 2022. 8. 23. 00:10

미리 보면 좋은 유튜브 !

https://youtu.be/tosLBcAX1vk


<HTTP의 특성>

※HTTP 특성 : Stateless / Connectionless = 한번의 요청/응답 시 모든 연결은 끊김. 상태도 종료됨

 

<쿠키 vs 세션 vs 토큰>

❗ 쿠키와 세션 모두 HTTP 에 상태 정보를 유지(Stateful)하기 위해 사용

즉, 쿠키와 세션을 통해 서버에서는 클라이언트 별로 인증 및 인가를 할 수 있게 됨

 

 ① 쿠키 Cookie

 - > 시스템을 옮기는 매개체/클라이언트와 서버 사이의 요청/응답에 더해지는 매개체

 - > 클라이언트에 저장될 목적으로 생성한 작은 정보를 담은 파일

 

② 세션 Session : 로그인 시 쿠키가 세션을 저장해서 계속 로그인된 상태인 것 처럼 보이게 요청/응답을 하는 것

-> 서버에서 일정시간동안 클라이언트 상태를 유지하기 위해 사용 (로그인 상태)

  • 서버에서 클라이언트 별로 세션ID를 부여한 후 클라이언트 별 정보를 서버에 저장
  • 세션 ID는 클라이언트의 쿠키값 (세션쿠키)으로 서버에 저장되어 식별에 사용됨.

③ 토큰 Token = ID 카드?자유이용권? 서버가 기억하는 이상한 문자열 =>JWT도 토큰 중 하나!

 

❗❗로그인 시 토큰이 더 나은 이유? (세션 방식보다 토큰이 더 나은 이유?)

  • 세션 
    • 클라이언트당 정보를 따로 DB에 저장해주어야 함!
    • (클라이언트에게는 계속 연결된걸로 보이지만) 끊임없이 Session ID를 요청하고 응답해야함 (DB에 접속)
  • 토큰
    • 로그인 시 처음에만 회원 DB를 확인하고 확인 토큰 (Access Token)부여
    • 추후 로그인하여 요청/응답 시행시 다시 DB에 접속할 필요가 없이 Token에 부여된 정보만으로 로그인 연결을 보여줄 수 있음. 

❗❓보안 : 토큰을 훔치면?? 

  •  토큰의 만료기간을 짧게 한다 => Refresh Token을 도입한다!
    • Refresh Token : Access Token의 재발급용
    • (Access Token의 만료시간을 짧게 하고 Refresh Token을 재발급하여 증정.Access Token보다 만료시간이 긺. 만료시 재로그인하도록)

④ JWT Json Web Token : Json 형식의 웹 토큰

 

※ MSA (Micro Service Architecture) : 단일 프로그램을 각 컴포넌트 별로 나누어 작은 서비스의 조합으로 구축하는 방법.

Monolithic Architecture Service에서 MSA로 바뀌면서 각 서비스별 별도의 DB 가 생성됨.

그러면서 처음 회원 - 로그인으로 Access Token으로 접근 후 주문으로 들어가게되면 다시 회원DB를 검색하면서 Overload(과부하)가 발생됨 

=> 과부하를 방지하기 위해서 느슨한 결합 / 낮은 의존성의 필요성이 대두 됨

=>JWT를 사용하자! 

  • JWT 사용
    • 로그인 정보를 Server에 저장하지 않고, client에 로그인 정보를 JWT 로 암호화 하여 저장 -> JWT를 통해 인증/인가
    • 모든 서버에서 동일한 Sceret Key 소유
    • Secret Key 통한 암호화 / 위조 검증 (복호화 시)

  • JWT 장/단점
    1. 장점
      • 동시 접속자가 많을 때 서버 측 부하 낮춤
      • Client, Sever 가 다른 도메인을 사용할 때
        • 예) 카카오 OAuth2 로그인 시 JWT Token 사용
    2. 단점
      • 구현의 복잡도 증가
      • JWT 에 담는 내용이 커질 수록 네트워크 비용 증가 (클라이언트 → 서버)
      • 기생성된 JWT 를 일부만 만료시킬 방법이 없음
      • Secret key 유출 시 JWT 조작 가능
  • JWT 사용 흐름 Overview
    1. Client 가 username, password 로 로그인 성공 시
      1. "로그인 정보" → JWT 로 암호화 (Secret Key 사용)
      2. JWT 를 Client 응답에 전달
      3. Client 에서 JWT 저장 (쿠키, Local storage 등)
    2. Client 에서 JWT 통해 인증방법
      1. JWT 를 API 요청 시마다 Header 에 포함
        Content-Type: application/json
        **Authorization: Bearer** **<JWT>
        ...**
        
      2. 예) HTTP Headers
      3. Server
        1. Client 가 전달한 JWT 위조 여부 검증 (Secret Key 사용)
        2. JWT 유효기간이 지나지 않았는지 검증
        3. 검증 성공시,
          1. JWT → "로그인 정보" (UserDetailsImpl) 만들어 사용
          2. ex) GET /api/products : JWT 보낸 사용자의 관심상품 목록 조회
  • JWT의 구조
    • JWT 는 누구나 평문으로 복호화 가능
    • 하지만 Secret Key 가 없으면 JWT 수정 불가능
    • → 결국 JWT 는 Read only 데이터

  • Header : 토큰에대한 정보
  • Payload : Json 형태로 필요한 정보가 들어감. Data
  • Verify Signiture : header + payload 를 해당 암호화 방식으로 암호화 (지정도 가능) / Access Token 생성 시 복호화

<JWT 로그인 이해> - Form Login 시!

  1. JWTAuthFilter : API 요청 Header 에 전달되는 JWT 유효성 인증
    1. 모든 API 에 대해 JWTAuthFilter 가 JWT 확인
    2. 로그인 전 허용이 필요한 API 는 예외처리 필요 ⇒ FilterSkipMatcher
      1. ex) 로그인 폼 페이지, 로그인 처리, css 파일 등
  2. FormLoginFilter : 회원 폼 로그인 요청 시 username / password 인증
  • 인증 성공 시 응답 (Response) 에 JWT 포함
  • : JWT 전달방법은 개발자가 정함