컴공생의 발자취

[내일배움캠프 31일차 TIL] 쿠키와 세션 그리고 JWT(Token) 본문

🤝 활동/내배캠TIL

[내일배움캠프 31일차 TIL] 쿠키와 세션 그리고 JWT(Token)

MNY 2024. 5. 31. 17:16
728x90
반응형
오늘의 진도 : 개인과제 6단계 회원가입까지...

어제는 jwt의 헤더와 쿠키에 대해 알아봤는데..
그렇다면 쿠키,  세션, JWT 그리고 토큰은 또 뭔데!?!?? 앞이 막막하다...
오늘의 학습, 지난 날의 궁금증, 개인과제, 면담, 오늘의 회고 이렇게 5개의 큰 틀로 나누어 정리할 것이다.

 

💡 오늘의 학습 키워드

- 개인과제 -
쿠키와 세션 사용하는 이유?
쿠키 & 세션
JWT(Token)
대부분의 IT 대기업이 JWT를 사용하지 못하는 이유?

 

쿠키세션 사용하는 이유?

: HTTP 프로토콜의 특성 비연결성(Connectionless)무상태(Stateless)를 보완하기 위해서 사용한다.

 

HTTP 프로토콜이란? 

인터넷상에서 데이터를 주고 받기 위하여 웹브라우저와 웹서버 간에 따르는 프로토콜

접속유지는 최소한으로 할 수 있기 때문에, 더 많은 유저의 요청을 작은 리소스로 처리할 수 있다는 장점이 있다.

하지만, 요청 간의 의존관계가 없기 때문에, 현재 접속한 유저가 이전의 접속한 유저와 같은지 확인할 방법이 없다. 또한, 같은 유저인지 확인하려면 지속적으로 인증을 해줘야 하는 번거로움이 있다.

 

비연결성(Connectionless)은 클라이언트가 서버에 요청을 보내고, 서버가 응답을 보내면 연결이 바로 종료된다.

각각의 요청은 독립적으로 처리되며, 서버는 클라이언트와의 연결을 유지하지 않는다. 

 

무상태(Stateless)은 이전 요청과 관련된 정보를 서버가 기억하지 않는다. 

각각의 요청은 서버에 도착할 때마다 독립적으로 처리되며, 이전 요청과는 관련이 없다. 이는 서버 측에서 사용자 상태를 유지하지 않고 각각의 요청을 독립적으로 처리함으로써 확장성이 높아지고 서버 부하가 분산된다.

 

쿠키 & 세션

쿠키(Cookie)

: 사용자의 컴퓨터(클라이언트 PC)에 저장하는 작은 기록 정보 파일

 

특징

  • 클라이언트 측 저장
  • key-value 쌍으로 구성
  • 사용자가 따로 요청하지 않아도 브라우저가 Request시에 Request Header를 자동으로 넣어서 서버에 전송
  • 도메인 당 20개의 쿠키
  • 하나의 쿠키는 4KB(=4096 byte)까지 저장이 가능

 

동작 방식

  • 4. 주로 'set-cookie' 헤더를 통해 HTTP 응답에 포함되어 클라이언트에게 전송
  • 5. 브라우저에 의해 자동으로 관리되는 쿠키 저장소에 저장
  • 6. 이후 클라이언트가 해당 사이트의 다른 페이지 리소스를 요청할 경우
    • 브라우저가 자동으로 쿠키를 저장하여 요청

 

한계점

  • 크키 제한 : 대용량 데이터를 다루기에 제한이 있다.
  • 보안 문제 : 쿠키는 클라이언트 측에 저장되기 때문에 보안에 취약하다. 클라이언트는 쿠키에 저장된 데이터를 직접 확인하고 수정할 수 있다. 이로 인해 데이터의 무결성이 위협될 수 있다.

* 이러한 한계를 극복하기 위해 세션이 도입되었다!

 

세션(Session)

: 쿠키를 기반으로 하고 있지만 사용자 정보 파일을 브라우저가 관리하는 쿠키와 달리 세션은 서버 측에서 관리


예시)
지정좌석 야구장 티켓!

* 사용자가 로그인에 성공하면 서버는 티켓을 생성해서 일부분을 찢은 뒤, 반쪽은 사용자의 브라우저로 보내고 다른 반쪽은 스태프가 가지고 있는다. 스태프와 사용자가 모두 하나의 티켓 정보를 각자 가지고 있다는게 중요한 점!

 

특징

  • 서버 측 저장
  • 세션은 서버 측에 저장되므로 데이터의 크기나 유지 기간에 대한 제한이 쿠키보다 적다.
  • 보안 : 서버 측에 저장되기에 클라이언트는 세션 데이터를 직접 수정할 수 없으며, 세션 식별자를 통해서만 접근 가능
  • 고유성 : 각 세션은 고유한 세션 식별자(session ID)에 의해 식별된다. 이 세션 식별자는 클라이언트에게 쿠키로 전달되어 세션을 식별하고 관리하는 데 사용
  • 일시적인 성격 : 웹 브라우저가 열려 있는 동안에만 유지, 브라우저가 닫히면 세션 데이터는 소멸

 

동작 방식

  • 4. 생성된 세션 정보와 세션 ID는 서버의 세션 저장소(메모리, 데이터베이스 등)에 저장
  • 5. 서버는 응답 헤더에 'set-cookie'를 사용하여 세션 ID를 클라이언트에게 전달
    • ex) Set-Cookie: sessionID=abc123; Path=/; HttpOnly; Secure Content-Type: text/html; charset=UTF-8
  • 6. 이후 클라이언트가 해당 사이트의 다른 페이지 리소스를 요청할 경우!
    • 클라이언트는 서버로부터 받은 'set-cookie' 헤더를 읽고 해당 쿠키를 저장. 이 쿠키에는 세션 ID가 포함되어 있다.
    • 클라이언트는 이후 서버에 요청을 보낼 때마다 해당 쿠키를 요청 헤더에 포함하여 전송.

 

한계점

  • 서버 부하 : 세션은 서버 측에서 유지되기 때문에 서버 자원을 소비
  • 확장성 문제 : 세션 데이터를 공유하거나 동기화하는 데 추가적인 구현 필요
  • 메모리 사용 :  세션 데이터는 서버의 메모리에 저장. 따라서 세션 데이터의 크기가 크거나 사용자 수가 많은 경우 서버의 메모리 부족 문제 발생
  • 세션 공격 : 세션 식별자(session ID)가 탈취/조작되는 경우 보안 문제 발생
  • 세션 만료 : 일정 시간이 지나면 세션은 만료. 만료 시간이 너무 길면 보안 문제, 짧으면 사용자 경험 저하.

* 이러한 한계를 극복하기 위해 JWT가 도입되었다!

 

JWT(Json Web Token)

: Json으로 된 웹 토큰

 

예시) 영화관 티켓

사용자가 로그인을 하면 토큰이라는 티켓을 건네준다.

이번에는 세션처럼 찢어서 주는 것이 아니라 그냥 주는데, 서버(스태프)가 무언가를 가지고 있지 않는 즉, 기억하지 않는다는 이야기다.

 

서버는 사용자가 요청과 함께 실어보낸 토큰의 1번 헤더와 2번 페이로드, 그리고 '서버에 감춰놓은 비밀값' 이 셋을 헤더에서 명시한 암호화 알고리즘에 넣고 돌린다. 그리고 그것이 3번 서명 값과 일치한다면 인가하게 된다.

 

특징

  • 서버 부하 감소 : 서버 측에서 세션 상태를 유지하지 않으므로 서버 부하가 줄어든다.
  • 확장성 : 각 요청에 인증 정보가 포함되어 있기 때문에 서버 간 상태 공유가 필요없다.
  • 무상태(Stateless) : JWT는 상태가 없는 상태를 유지하므로 클라이언트와 서버 간의 통신에 상태를 저장할 필요가 없다.
  • 보안성 : 디지털 서명을 통해 인증 정보를 보호하므로, 변경이나 위조를 방지할 수 있다. 서버에서 토큰을 생성할 때 비밀 키를 사용하여 서명하고, 클라이언트에서 토큰을 검증할 때 이 비밀 키를 사용하여 서명을 확인한다.
  • 다양한 플랫폼 지원 : JSON 포맷을 사용하고 간단한 구조를 가지고 있기 때문에 다양한 플랫폼과 기술에서 사용할 수 있다.

* Why?

대부분의 웹 애플리케이션은 JSON을 사용하여 데이터를 표현하고 전송하는데, JWT가 JSON을 사용하면 기존의 JSON 데이터와 쉽게 통합할 수 있다.

 

동작 방식

 

한계점

  • 토큰 크기가 클수록 네트워크 성능 저하
  • 토큰 탈취 시, 만료 시간까지 유효해 악용될 수 있다.
  • JWT의 무상태(stateless) 특성 때문에 서버에서 즉시 무효화할 수 없다.

* Why?

JWT는 토큰을 발급한 후에는 서버에서 해당 토큰을 추적하거나 관리하지 않기 때문입니다.서버에서 즉시 무효화를 위해서는 토큰 검증을 하는 비밀 키를 변경하거나, 취약한 토큰을 관리하여 차단하는 등의 방법을 사용해야 합니다. 하지만 이러한 과정을 추가적인 복잡성을 동반하며, 실시간으로 토큰을 무효화하는 데에 어려움을 가지고 있습니다.

 

대부분의 IT 대기업이 JWT를 사용하지 못하는 이유?

세션처럼 Stateful해서, 모든 사용자들의 상태를 기억하고 있다는 건 구현하는 것이 부담되고 고려사항도 많지만 구현만 한다면 기억하는 대상의 상태들을 언제든 제어할 수 있다는 의미가 된다.

예를 들어 한 기기에서만 로그인 가능한 서비스를 만들려고 하는 경우 PC에서 로그인한 상태의 어떤 사용자가 핸드폰에서 또 로그인하면 PC에서는 로그아웃되도록 기존 세션을 종료할 수 있는 것이다.

JWT 방식에서는 이미 줘버린 토큰을 뺏을 수도 없고 그 토큰의 발급 내역이나 정보를 서버에서 기록하거나 추적하고 있지 않기에 통제가 안되는 것이다. 또 어떤 해커가 토큰을 탈취한 경우 해당 토큰을 무효화할 방법도 없게된다.

 

이러한 이유로 실 서비스 중 JWT 만으로 인가를 구현하는 곳은 많지 않다.

 

이를 보완해주는 방법은 아래의 블로그!

// 더 이상 정리할 힘이 없다.. JWT 어려운 녀석..

// 대충 여기까지만 알아도 성공일지도?

 

* 참고한 블로그

 

세션 vs 토큰 vs 쿠키, JWT란? (인증과 인가의 차이, authentication authorization 차이, 세션과 쿠키의 개념

로그인을 구현한다면 꼭 알아야 할 개념들이다. 이번에 프로젝트를 진행하면서 Next-Auth를 사용해 소셜 로그인을 구현했는데, 이때 공부한 내용들과 실제 프로젝트에서 사용한 인증, 인가 방법에

kbwplace.tistory.com

 

 

 

인증 방식(쿠키, 세션, JWT)에 대해 알아보자

이번 글에서는 웹 어플리케이션의 인증 방식에 대해 알아보려고 한다.인증 방식을 알아가기에 앞서, 인증과 인가란 무엇인지, 웹 어플리케이션 인증에 어떤 특수성이 있는지, 어떤 인증 방식이

velog.io

 


지난 날의 궁금증

  • 아직 해결하지 못한 궁금증(더보기 ..Click)
더보기
  • Q : PUT vs UPDATE vs PATCH ?
  • Q : Cookie + JWT 같이 사용하는 이유?

 


개인과제

  • 현재까지 진행 상황
    • 6단계 일부 : 튜터님께 가서 모른다고 찡찡댄 결과물
  • 만들지 못한 이유에 대한 고촬 (숙제 제출 후 고촬)

지난 시간 jwt의 인증 방식을 cookie에서 header로 변경 후..

그 앞의 댓글을 jwt 인증/인가를 적용해주기 위해서는 일단 회원가입이 필요하다고 판단!

그래서 회원가입을 해야지.. 하고 강의에서 했던 프로젝트 mySelectShop을 봤는데, 대참사다.

UserController, JwtAuthenticationFilter, JwtAuthorizationFilter, UserDetailsImpl, UserDetailsServiceImpl, 그 외..

뭔가 많이 묶여있다. 일단 많이 묶여있으니 들고왔는데.. 그 묶여 있는게 당최 어떻게 돌아가는지 모르겠다. 이 전에는 프론트가 안 묶여있었기에 어떻게 동작하는지 감이 안 잡혔다. 일단 이해해보기 위해 노력은 해보았지만 안되겠어서 튜터님께 찾아갔다.

 

그러고 내가 도저히 모르겠던 부분!을 어떤 방식으로 흐름을 변경하면 되는지 알려주셨다!

 

  • 변경 전 UserContorller > signup
    @PostMapping("/user/signup")
    public String signup(@Valid SignupRequestDto requestDto, BindingResult bindingResult) {
        // Validation 예외처리
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        if(fieldErrors.size() > 0) {
            for (FieldError fieldError : bindingResult.getFieldErrors()) {
                log.error(fieldError.getField() + " 필드 : " + fieldError.getDefaultMessage());
            }
            return "redirect:/api/user/signup";
        }

        userService.signup(requestDto);

        return "redirect:/api/user/login-page";
    }
  • 변경 후 UserContorller > signup
    @PostMapping("/user/signup")
    public ResponseEntity<CommonResponse<SignupResponseDto>> signup(@Valid @RequestBody SignupRequestDto requestDto) {
        User user = userService.signup(requestDto);
        SignupResponseDto response = new SignupResponseDto(user);
        return ResponseEntity.ok()
                .body(CommonResponse.<SignupResponseDto>builder()
                        .statusCode(HttpStatus.OK.value())
                        .msg("회원가입이 완료 되었습니다.")
                        .data(response)
                        .build());
    }

 

* 깃허브 레파지토리

 

GitHub - ysy56/mySelectShop: 내배캠[주특기 입문] - Spring 숙련 2주차

내배캠[주특기 입문] - Spring 숙련 2주차. Contribute to ysy56/mySelectShop development by creating an account on GitHub.

github.com

 

 

GitHub - ysy56/agendaAppServer: 개인과제 두 번째 : 나만의 일정 관리 앱 서버

개인과제 두 번째 : 나만의 일정 관리 앱 서버. Contribute to ysy56/agendaAppServer development by creating an account on GitHub.

github.com

 


면담

  • 현재 상황 + 질문

jwt인증 방식 header로 변경 후 회원가입에 대해 하고 있는데,

프론트 부분이랑 많이 엮여 있어서 동작 흐름에 대한 이해 불가

뭐부터 건드려야 할지 모르겠어요..

 

  • 결과

개인과제 부분과 같이 UserContorller를 기준으로 Service, Repository를 이전 과제 Agenda의 CRUD 작성한 것과 같이 튜터님과 같이 흐름을 따라가면서 변경. 회원가입 6단계의 일정 조건을 제외하고 구현 완료!

 


오늘의 회고

  • 12시간 중 얼마나 몰입했는가?

회원가입 수정 못한다고 좌절한 시간이 절반 이상이라서..

튜터님과 면담하고 수정한 시간을 가진 2-3시간 정도?

 

  • 오늘의 생각

쿠키, 세션, JWT의 특징과 왜 그것이 나오게 되었는지 흐름을 드디어 알게 되었다.

이제 내가 작성한 코드에서 Filter이랑 security가 어떻게 사용되는지만 알면 좋겠는데.. 

 

오늘의 TMI : TIL 우수 사례로 뽑히는 거 포기함.

-> 빠른 포기는 정신 건강에 좋다!

 

  • 내일 학습할 것은 무엇인지

과제 제출 이후 필수 기능 구현의 예외 부분, 코드를 일관성 있게 변경하기.

 

728x90
반응형