백엔드 데브코스 TIL 46-47일차

Inchang Choi·2022년 6월 11일
1

백엔드 데브코스 TIL

목록 보기
30/30
post-thumbnail

학습목표

강의를 들으며 내가 알고 있는 내용을 점검하고,

새로 배운 내용을 정리하며,

궁금한 내용을 알아가며 학습해나가는 것을 목표로 합니다.

REST API 서비스와 Stateless 아키텍처

SPA(Single Page Application), 안드로이드/아이폰 모바일 앱 등을 위해 API를 제공하는 서버에서는 Spring Security를 어떻게 활용할 수 있을까요?

REST API

REST API 서비스 개발을 위한 가장 일반적인 접근 방법이며 (사실상) 표준입니다.

그러나 엄격하게 REST API 디자인 원칙을 따르는 것은 쉽지 않습니다.

하지만 통상적으로 이러한 API들을 REST API 라고 부르고 있습니다.

Java, Python, Go 등 다양한 언어로 풍부한 레퍼런스가 존재 하기 때문에 구현이 용이합니다.

HTTP 프로토콜 기반만 따르면 어떤 기술이든 응용이 가능합니다.(XML, JSON)

앞에서 알아본 3-Tier Architecture 구조와 REST API 서비스를 궁합이 매우 좋으며, 3-Tier Architecture의 장점 대부분은 REST API 서비스를 개발/운영할때 여전히 유훃바니다.

REST API 서비스에서 Session을 꼭 써야 하는가에 대해서는 서비스 성격에 따라 고민이 필요한 부분입니다.

Stateful vs Stateless

Stateful 아키텍처의 장단점

일단 Session을 사용하고 있으면, Stateful 하다고 할 수 있습니다.

그러나 앞서 살펴본 것처럼 수평확장(Scale-Out) 과정이 쉽지 않음

즉, Session Cluster가 반드시 필요하게 됩니다.

그렇기 때문에 Session Cluster의 장애 또는 성능 병목이 서비스 전체에 큰 영향을 줄 수 있습니다.

단일 사용자의 다중 로그인 컨트롤, 사용자 유효성 체크, 강제 로그아웃 기능 구현이 쉽다는 장점이 있습니다.

Stateless 아키텍처의 장단점

Session을 전혀 사용하지 않아야 합니다. 사실 HTTP 프로토콜 자체가 Stateless를 띄고 있습니다.

수평확장이 매우 쉽고, Session Cluster가 필요 없습니다.

그러나 단일 사용자의 다중 로그인 컨트롤, 사용자 유효성 체크, 강제 로그아웃 기능 구현이 어렵습니다.

무엇보다 완전한 Stateless 아키텍처 기반으로 유의미한 서비스 개발이 어렵습니다.

완전한 Stateless 서비스는 정적 리소스(html, css, javascript, 이미지 등)를 서비스 하는데 적합합니다.

예: AWS S3

서버는 어떤식으로는 사용자를 식별할 수 있어야 합니다. (단, Session 사용 금지)

JWT

JWT 개요

JSON 포맷을 사용하여 데이터를 만들기 위한 웹 표준 (RFC 7519)

JWT는 자체적으로 필요한 모든 정보를 지니고 있습니다. (self-contained)

  • 토큰에 대한 메타정보 (토큰타입, 사용된 해시 알고리즘)
  • 사용자 정의 데이터
  • 토큰 유휴성 검증을 위한 데이터

인터넷상에서 쉽게 전달할 수 있습니다.

  • URL-Safe 텍스트로 구성되기 때문에 HTTP 프로토콜의 어느 위치에든 들어갈 수 있다. (보통 HTTP 헤더에 들어감)

위변조 검증이 가능합니다.

  • 토큰이 위변조되지 않았음을 증명하는 서명(Signature) 포함

JWT 구조

Header, Payload, Signature 세 부분으로 구성됩니다.

Header, Payload, Signature 세 부분을 Base64 Url-Safe 방식으로 인코딩하고 dot(.)을 구분자로 결합합니다.

Header

JWT를 검증하는데 필요한 정보를 담고 있습니다. (토큰 타입, 사용된 알고리즘)

  • 알고리즘은 HMAC, RSA 방식을 지원합니다.
  • 아래 그림에서 HS512는 HMAC using SHA-512를 의미합니다.
  • HMAC 알고리즘에서 비밀키는 최소한 알고리즘의 서명 길이만큼의 비트를 가지고 있어야 함합니다.(HS512 : 64byte)

Payload

JWT를 통해 전달하고자 하는 데이터이며 Claim-Set 이라고 합니다.

  • Claim 자체는 쉽게 말해 Key-Value 데이터 쌍을 의미합니다.

JWT 자체는 암호화되는 것이 아니기 때문에 민감정보를 포함해서는 안됩니다.

Reserved Claims, Public Claims, Custom Claims 으로 구분됩니다.

  • Reserved Claims — 미리 등록된 Claims 필수적으로 사용할 필요는 없지만 사용을 권고합니다.
    • iss : 토큰을 발급한 발급자 (Issuer)
    • exp : 만료시간이 지난 토큰은 사용불가
    • nbf : Not Before의 의미로 해당 시간 이전에는 토큰 사용불가
    • iat : 토큰이 발급된 시각
    • jti : JWT ID로 토큰에 대한 식별자
  • Public Claims 사용자 마음대로 쓸 수 있으나 충돌 방지를 위해 미리 정의된 이름으로 사용을 권고합니다.
  • Custom Claims 사용자 정의 Claims (Reserved, Public 에 정의된 이름과 중복되지 않도록합니다.

Signature

토큰 생성 주체만 알고 있는 비밀키를 이용해 헤더에 정의된 알고리즘으로 서명된 값

토큰이 위변조 되지 않음을 증명합니다.

String concatenated = encodedHeader + '.' + encodedClaims
String token = base64URLEncode(hmacSha512(concatenated, key))

JWT 장단점 : Stateful vs. Stateless

장점

  • 사용자 인증에 필요한 모든 정보는 토큰 자체에 포함하기 때문에 따로 스토리지가 필요 없습니다.
  • 수평확장이 매우 쉽고 Session Cluster가 필요 없습니다.
  • 따라서, Active User가 많은 서비스에서 JWT 사용이 유리합니다.

Session을 사용할 경우 Active User 수 만큼 Session을 저장해야 하기 때문에 스토리지 관리가 어려워집니다.

단점

  • 토큰 크기를 가능한 작게 유지해야 합니다.
  • 토큰 자체가 항상 HTTP 요청에 포함되어야 하기 때문에 토큰이 커질수록 불리합니다.
  • 유효기간이 남아 있는 정상적인 토큰에 대해 강제적으로 만료 처리가 어렵습니다.

Session을 사용할 경우 동시 Session 제어, Session 만료 처리 등 보안상 이점이 있습니다.

profile
always positive

0개의 댓글