본문 바로가기

Server Programming/BackEnd Project

[패스트캠퍼스 백엔드 개발자 부트캠프] 3. 서버의 진화 과정과 보안

반응형

개요

  • 서버의 진화과정을 살펴보면서 궁극적으로 추구하는 방향에 대해서 탐구한다.
  • 성능이 좋고, 안정적인 서버의 개발을 위해 필요한 기술들이 어떤 것들이 있는지 알아보고 이를 학습한다.
  • 프로젝트를 수행하기 전, 좋은 서버를 개발하기 위해 필수 조건에 충족하도록 프로젝트 가설계를 수행한다.

 

목차

  1. 서버의 진화 과정
  2. 비슷하지만 다른 개념 정리
  3. 대표적인 악의적 요청 방식
  4. 스프링 부트의 발전 과정
  5. 악의적인 요청 방지 방법
  6. 결론

 

https://github.com/ji-hoooon/sessionandcookie

 

GitHub - ji-hoooon/sessionandcookie: 세션과 쿠키 학습을 위한 리포지토리

세션과 쿠키 학습을 위한 리포지토리. Contribute to ji-hoooon/sessionandcookie development by creating an account on GitHub.

github.com


서버의 진화 과정

  1. 초기의 stateless 서버
  2. 세션과 쿠키를 이용한 stateless 서버로의 발전 
  3. JWT를 이용한 stateless 서버

초기의 stateless 서버

  • 초기의 서버는 정적 데이터를 요청시 응답해주는 서버로, GET요청만이 존재했다.
  • 클라이언트의 상태를 저장하지 않기 때문에, 요청하는 클라이언트의 정보와 관계없이 동일한 요청에 동일한 응답만이 가능했다.
  • 모든 요청에 대해 독립적으로 처리하기 때문에 처리 속도가 빠르고 확장성이 높다.

 

세션과 쿠키를 이용한 stateless 서버로의 발전 

  • 세션 방식의 인증 등장
  • 초기의 stateless 서버는 인증 상태를 유지하기에 어려움이 있었기 때문에 이에 대한 대안으로 세션과 쿠키가 등장하게  되었다.
  • 클라이언트의 첫 요청에 서버는 세션ID를 생성해 서버의 세션 저장소에 저장하고, 응답헤더에 set-cookie 세션 ID를 담아서 클라이언트에 전달한다.
  • 2번째 요청부터 클라이언트 브라우저의 쿠키영역에 저장된 쿠키를 요청 헤더에 담아서 전달한다.
  • 서버에서 요청 헤더의 쿠키를 보고, 서버의 세션 저장소에 해당 세션ID가 있는지 확인한 후 존재하면 사용자 인증을 수행한다.
  • 이후 클라이언트의 모든 요청에 세션ID를 함께 전달해 인증상태를 유지하게 된다.

세션과 쿠키 (1)
세션과 쿠키(2)

JWT를 이용한 stateless 서버

  • 토큰 방식의 인증 등장
  • 서버에서 세션을 저장해야하는 stateful 서버는 세션을 관리해야하는 단점이 존재한다.
  • 특히, 로드 밸런서 서버의 경우 세션저장소가 분리되어 서버의 상황에 따라 서버를 선택하기 때문에 요청에 따라 세션저장소에 세션ID의 존재여부가 달라지는 단점이 존재하게 되었다.
  • 이처럼 서버에서 세션을 관리해야 하는 어려움이 발생하게 되었고, 이는 토큰 방식의 인증이 등장하게 된 배경이 되었다.

  • JWT (Json Web Token)은 서명된 토큰을 인증 수단으로 사용하는 방식으로 서버가 세션을 저장하지 않고, 서버에서 토큰을 생성한 후 사용자에게 전달하면 사용자의 브라우저에 토큰을 저장하고 있다가 요청시마다 토큰 함께 전달하는 방식으로, 서버에서 전달받은 토큰을 생성해 전달받은 토큰과 일치하는지 검증을 통해 인증을 수행한다.
  • 서버에 세션을 저장하지 않기 때문에 세션을 관리해야하는 단점을 해결할 수 있고,  헤더, 페이로드를 각각 Base64로 인코딩 후, 시그니처의 경우 RSA(공개키 알고리즘) 혹은 RMAC512(대칭키 알고리즘)으로 암호화 한다. 전달 받은 토큰을 검증하는 과정은 RSA 또는 RMAC512를 통해 암호화하기 때문에 보안성도 높다.

JWT 구조
JWT 서명 암호화 처리


비슷하지만 다른 개념 정리

 

  1. 보호와 보안
  2. 인증과 인가
  3. 예외와 에러
  4. 검증과 검사

 

보호와 보안

  • 보호는 데이터의 기밀성, 무결성, 가용성을 지키는 것
  • 보안은 외부 공격, 데이터 유출과 같은 보안 위협으로부터 지키는 것
  • 일반적으로 스프링 시큐리티 프레임워크의 필터를 이용해 디스패처서블릿으로 전달되기 전에  악의적인 요청을 필터링하거나 혹은 인터셉터를 이용해 컨트롤러로 전달되기 전, 후에 악의적인 요청을 미리 처리한다.

인증과 인가

  • 인증은 시스템의 보안을 유지하기 위해 사용자의 신원을 검증하는 것
  • 인가는 인증된 사용자에게 권한을 부여하는 것
  • 일반적으로 스프링 시큐리티를 통해 인증 처리와 권한 확인이 필요한 메서드에 인터셉터로 구현하고, 공통 처리해 중복 코드를 제거한다.

예외와 에러

  • 예외는 정상적인 프로그램 실행 흐름에서 예측 가능하고 복구 가능한 상황을 말하며, try-catch블럭으로 직접 처리하거나 호출한 메서드로 예외를 던지는 방식으로 예외처리를 수행한다.
  • 에러는 일반적으로 시스템 수준에서 발생하는 심각한 오류로, 프로그램에서 복구할 수 없는 상황으로 처리가 불가능해 비정상 종료되므로 에러가 발생하지 않도록 코드를 설계하는 것이 중요하다.
  • 일반적으로 커스텀 예외클래스를 작성하고, @ControllerAdvice 어노테이션과 @ExceptionHandler 어노테이션을 사용해 예외 종류에 따라 공통적으로 예외를 처리해 중복 코드를 제거한다.

검증과 검사

  • 검증은 데이터의 유효성을 검증하는 일컬는 것으로, 입력값이 유효한지 확인하는 것
  • 검사는 출력값이 정확하게 출력되는지 확인하는 것
  • 검증의 경우 일반적으로  Bean Validation API로 구현하는데 객체의 필수 필드 값이 존재하는지, 형식이 맞는지, 범위를 벗어나지 않는지 등을 검증을 수행해 입력값의 유효성을 검증한다.
  • 검사의 경우 일반적으로 JUnit, AssertJ 등의 테스트 프레임워크를 사용한다. 테스트 케이스를 작성하고, 해당 테스트 케이스를 실행하여 특정 조건에서 예상한 대로 동작하는지 확인한다.
    • 단위 테스트 : @MockMvcTest, @WebMvcTest, @DataJpaTest
    • 통합 테스트 : @SpringBootTest

대표적인 악의적 요청 방식

  1. SQL Injection
  2. 인증 안 된 사용자의 페이지 요청
  3. 권한이 없는 사용자의 페이지 요청
  4. CORS 공격
  5. XSS 공격
  6. CSRF 공격

스프링 부트의 발전 과정

  1. XML을 이용한 서버 설정
  2. 어노테이션을 이용한 서버 설정
  3. 설정클래스를 이용한 서버 설정

악의적인 요청 방지 방법

  1. SQL Injection 방지
  2. 인터셉터 혹은 필터를 이용한 인증 체크
  3. 인터셉터 혹은 필터를 이용한 인가 체크
  4. CORS 공격 방지
  5. XSS 공격 방지
  6. CSRF 공격 방지

결론

프로젝트에 사용할 기술

  1. 백엔드 : REST API + Spring Boot
  2. DB : MySQL + Spring Data JPA
  3. 보안 : Spring Security + JWT
반응형