쿠키 세션 토큰 캐시

이수연·2023년 4월 6일
1

안녕하세요. 앞서 소개드렸던 restful에 이어 쿠키,세션,토큰,캐시 관련 공부하여 정리하려 합니다.
챕터는 역사, 개념적 설명, 쓰이는 방식/사례 순서로 소개해 드리겠습니다.

쿠키

먼저 쿠키를 설명하기전, stateless 개념에 대해 알아야 쿠키에 대해 이해할수 있기 때문에 stateless관련 설명 먼저 하겠습니다.

stateless

stateless는 비연결성이라는 뜻으로 서버와 클라이언트가 통신하고 난후 그 상태를 그대로 유지하는것이아닌 상태를 끊어주는것 입니다. 따라서 클라이언트가 새로 같은 요청을 하면 서버는 기억을 하지 못하는 특성을 가지고 있습니다.

stateless의 문제점: 모든 요청에 사용자 정보가 포함되도록 개발 해야함

쿠키 역사와 개념

이러한 http의 stateless 속성으로 인하여 이를 보안하기위하여 쿠키와 세션이 등장했습니다.

HTTP 쿠키는 1994년 넷스케이프 커뮤니케이션즈(Netscape Communications)에서 개발되었습니다.
쿠키란 클라이언트를 식별하는데 사용하는 웹 서버가 클라이언트 컴퓨터에 저장한 정보의 일부 입니다.
아래의 사진과 같이 클라이언트에서 유저정보를 담아 서버측에 요청을 보내면 서버측에서는 Set-Cookie 메서드를 이용하여 쿠키저장소에 해당유저의 정보를 저장합니다. 이로 인하여 이후에 다른 페이지에 이동을 하더라도 클라이언트는 쿠키에 저장되어 있는 정보를 조회하여 로그인 상태가 유지 될수 있도록 할수 있습니다.

서버에서 HTTP Response Header에 set-cookie 속성을 이용하여 클라이언트에 쿠키를 제공한다.
이름, 값, 만료 날짜/시간(쿠키 저장시간), 경로 정보들이 들어있다.
( 쿠키의 정보를 활용하면 헨젤과 그레텔처럼 사용자의 활동을 추적할 수 있게 된다. (잘 활용하면 사용자에 활동에 맞는 상품들을 추천할 수 있게 된다.)
클라이언트의 상태 정보를 HTTP 요청에 참고해서 서버에 보내어 서버측에서는 추가적인 메타데이터를 확보하여 클라이언트의 상태를 확인할 수 있는 것이다. ( 로그인, 장바구니 등등. )

쿠키의 특징

  • 서버가 웹 페이지(응답)를 요청한 브라우저에 보낼 때, 브라우저가 저장하기로 되어 있는 부가적인 텍스트 덩어리(4000바이트[4KB])가 포함될 수 있다.

  • 이러한 각 덩어리를 쿠키라고 표현한다.

  • 브라우저는 같은 서버에 요청을 보낼때 쿠키를 같이 전송한다. [ 서버측에서는 클라이언트에 고유한 식별 번호를 할당한다. ]

  • 서버는 클라이언트의 메모리를 사용하여 식별 번호를 클라이언트의 이전 방문에 대한 정보를 기억하게 하는 것이다.

  • 쿠키 정보는 항상 서버에 전송됨

쿠키 보안

  1. Secure

    • 쿠키는 http, https를 구분하지 않고 전송
    • Secure를 적용하면 https인 경우에만 전송
  2. HttpOnly

    • XSS 공격 방지
    • 자바스크립트에서 접근 불가(document.cookie)
    • HTTP 전송에만 사용
  3. SameSite

    • XSRF 공격 방지
    • 요청 도메인과 쿠키에 설정된 도메인이 같은 경우만 쿠키 전송

쿠키 종류

  1. 세션쿠키(Session)
  • 브라우저(클라이언트) 메모리에 있는 동안 유효합니다.
    ⇒ 브라우저가 종료되면 브라우저가 가진 메모리가 해제되면서 쿠키도 사라진다.
  1. 지속쿠키(Persistent)
  • 파일로 저장되어 브라우저가 종료되어도 쿠키는 남아있는다.
  • 파일로 저장되기에 비교적 보안에 취약한 점이 있다.

쿠키 프로세스 정리

  1. 브라우저는 서버에 웹 페이지를 요청한다.
  2. 서버는 HTTP 헤더에 쿠키 값을 넣어서 클라이언트에 응답한다.
  3. 클라이언트는 해당 쿠키를 저장한다.
  4. 클라이언트가 웹페이지를 요청한 서버에 재 요청할때 쿠키 정보를 HTTP 헤더에 담아서 요청한다.
  5. 서버는 HTTP 헤더에 쿠키가 있을 경우 그에 맞는 비즈니스 로직을 수행한다.

쿠키 단점

1.보안성 문제: 쿠키는 클라이언트에 저장되기 때문에 보안에 취약합니다. 쿠키 정보를 탈취하면 해커가 사용자 대신 웹 애플리케이션에 로그인할 수 있습니다.

2.개인 정보 노출: 쿠키에 저장된 개인 정보가 악의적인 사용자에게 노출될 가능성이 있습니다. 이를 방지하기 위해 쿠키에 저장할 정보를 최소화해야 합니다.

3.쿠키 크기 제한: 쿠키는 클라이언트의 브라우저에 저장되기 때문에, 브라우저마다 쿠키 크기 제한이 있습니다. 쿠키 크기가 제한을 초과하면 문제가 발생할 수 있습니다.

4.쿠키 만료: 쿠키는 만료 기간이 있습니다. 만료 기간이 지나면 클라이언트에서 해당 쿠키를 삭제합니다. 이때, 만료 기간을 길게 설정하면 보안성이 낮아질 수 있으며, 짧게 설정하면 사용자 경험이 저하될 수 있습니다.

5.사용자 설정에 따른 문제: 일부 사용자는 쿠키를 거부하거나, 쿠키를 삭제하는 설정을 사용합니다. 이 경우, 쿠키를 사용하는 기능이 제대로 작동하지 않을 수 있습니다.

쿠키 사용 예시

  1. 사용자 로그인 정보 저장: 사용자가 로그인을 하면, 서버에서는 사용자의 정보를 검증하고, 로그인 성공 시 클라이언트에게 쿠키를 발급합니다. 이후 사용자가 다른 페이지를 요청할 때, 클라이언트는 쿠키를 서버에 보내어 인증을 수행합니다.

  2. 사용자 선호도 저장: 사용자가 사이트에서 어떤 설정을 변경하거나, 어떤 상품을 찜하거나, 어떤 페이지를 방문했는지 등의 정보를 쿠키에 저장하여, 사용자의 선호도를 파악하고 추천 상품을 제공하는 등의 기능을 수행할 수 있습니다.

  3. 장바구니 기능: 사용자가 상품을 장바구니에 담으면, 클라이언트는 쿠키를 사용하여 장바구니에 담긴 상품 정보를 서버에 보냅니다. 이후 사용자가 결제를 하거나, 장바구니를 비우거나, 다른 페이지로 이동할 때, 서버는 이 쿠키 정보를 사용하여 장바구니 기능을 처리합니다.

  4. 광고 타켓팅: 광고 서비스에서는 사용자의 쿠키 정보를 수집하여, 사용자의 검색 기록, 관심사 등을 파악하고 이를 기반으로 광고를 제공합니다.

세션

세션이란 클라이언트와 서버 간의 연결을 유지하며 클라이언트의 상태 정보를 저장하고 관리하는 방법입니다. 세션은 서버 측에서 생성되며, 클라이언트의 요청과 응답에서 생성되는 데이터를 관리합니다. 클라이언트가 서버에 처음 요청을 보낼 때, 서버는 클라이언트를 식별하는 세션 ID를 생성합니다. 이후 클라이언트가 요청을 보낼 때마다, 서버는 해당 클라이언트의 세션 ID를 사용하여 클라이언트를 식별하고 상태 정보를 유지합니다.

세션의 역사

세션은 크게 3단계에 걸쳐 변화 하였습니다.

HTTP/1.1 (1997년): 세션은 쿠키를 보완하기 위해 도입된 방식으로, 사용자 정보를 서버 측에 저장합니다. 이 방식에서는 서버에서 클라이언트에게 세션 ID를 발급하고, 클라이언트는 이를 쿠키에 저장해두고, 이후 요청에서 서버에 이 세션 ID를 보내어 인증을 수행합니다.

HTTP/2 (2015년): HTTP/2에서 세션이라는 개념을 보다 발전시켜서 연결된 모든 요청과 응답을 하나의 세션 내에서 처리하도록 변경하였습니다. 이는 클라이언트와 서버 간의 연결을 효율적으로 관리하고, 요청과 응답을 병렬로 처리할 수 있도록 합니다. 단일 연결에서 여러 요청과 응답을 처리할 수 있게 되어, 지속적인 연결을 통해 처리하는 방식보다 더 빠른 성능을 제공합니다. ( stateless가 도입된것은 아니며 stateful방식이 개선되었다한다.)

HTTP/3 (2020년): 세션을 처리하는 방법이 변경되었다. 기존의 TCP 연결 대신, QUIC(Quick UDP Internet Connections) 프로토콜을 사용하여 더 빠르고 안정적인 세션 관리를 제공합니다. 이를 통해 HTTP/3는 더 나은 성능과 보안을 제공합니다.

QUIC(Quick UDP Internet Connections) 프로토콜은 Google에서 개발한 전송 프로토콜로, UDP(User Datagram Protocol) 기반으로 동작합니다. QUIC는 TCP와는 다르게 연결 설정 과정이 간소화되어 데이터 전송 속도가 더욱 빠릅니다. 또한, TCP와는 달리 데이터 전송과 연결 관리를 병렬적으로 처리할 수 있어서 더욱 효율적입니다. 또한, QUIC는 오류 정정 기능을 강화하여 데이터 전송에 대한 신뢰성과 안정성을 보장합니다. 이러한 기능들로 인해 QUIC를 사용하면 더욱 빠르고 안정적인 세션 관리를 제공할 수 있습니다.

세션 특징

1.상태 정보 유지: 세션을 사용하면 클라이언트와 서버 간의 상태 정보를 유지할 수 있습니다. 예를 들어, 로그인 정보나 장바구니 정보와 같은 상태 정보를 세션에 저장해서 다음 요청에서도 사용할 수 있습니다.

2.클라이언트 식별: 세션은 클라이언트를 식별할 수 있는 ID를 사용합니다. 이를 통해 클라이언트가 보내는 요청이 어떤 세션에 속해 있는지 식별할 수 있습니다.

3.보안 강화: 세션을 사용하면 쿠키(Cookie)와 같은 다른 기술보다 보안을 강화할 수 있습니다. 세션 ID를 쿠키나 URL 매개변수에 저장하는 방식은 클라이언트 측에서 변경할 수 있기 때문에 보안성이 낮습니다. 하지만, 세션 ID를 서버 측에서만 관리하는 방식을 사용하면 보안성을 높일 수 있습니다.

4.자원 소모: 세션은 서버 측에서 상태 정보를 유지하기 때문에 서버 자원을 사용합니다. 세션을 사용할 때는 세션 데이터의 크기와 유지 기간 등을 고려해서 서버 자원을 적절하게 사용해야 합니다.

5.세션 만료: 세션은 일정 시간이 지나거나 클라이언트가 로그아웃을 하면 종료됩니다. 이때 세션에 저장된 데이터는 일반적으로 삭제됩니다.

6.다중 탭/창 지원: 세션은 클라이언트를 식별하는 ID를 사용하기 때문에 다중 탭/창에서 동시에 사용해도 문제가 없습니다.

세션 프로세스 정리

  1. 클라이언트는 웹 브라우저를 통해 웹 서버에 요청(Request)을 보냅니다. 이때 요청 메시지는 HTTP 프로토콜을 따릅니다.

  2. 웹 서버는 요청을 받고 요청에 대한 응답(Response)을 생성합니다. 응답 메시지는 마찬가지로 HTTP 프로토콜을 따릅니다.

  3. 웹 서버는 응답 메시지를 클라이언트에게 전송합니다. 이때 응답 메시지에는 클라이언트가 요청한 정보가 포함됩니다.

  4. 클라이언트는 응답 메시지를 받아서 처리합니다. 일반적으로 웹 브라우저에서는 HTML, CSS, JavaScript 등을 해석해서 화면에 출력합니다.

  5. 세션이 필요한 경우에는 클라이언트와 웹 서버 간에 세션 ID를 주고받습니다. 이때 세션 ID는 일반적으로 쿠키(Cookie)나 URL 매개변수(Parameter)를 사용해서 전달됩니다. 이후 클라이언트가 요청을 보낼 때마다 세션 ID를 함께 보내서 웹 서버가 세션을 유지할 수 있도록 합니다.

  6. 세션을 유지하는 동안 클라이언트와 웹 서버는 계속해서 요청과 응답을 주고받습니다. 이때 세션 ID를 사용해서 클라이언트와 웹 서버가 동일한 세션을 사용하도록 합니다.

  7. 클라이언트가 세션을 종료하거나 일정 시간이 경과하면 세션은 종료됩니다. 이때 세션에 저장된 데이터는 일반적으로 웹 서버에서 삭제됩니다.

세션 사용 예시

  1. 로그인 상태 유지: 웹 사이트에서 로그인을 하면, 해당 사용자의 로그인 상태를 HTTP 세션을 사용하여 유지할 수 있습니다. 이를 위해 서버는 로그인 요청에 대한 인증을 수행하고, 인증이 완료되면 사용자 정보를 세션에 저장합니다. 이후 사용자가 웹 페이지를 요청할 때마다, 서버는 해당 세션에 저장된 정보를 확인하여 로그인 상태를 유지합니다.

  2. 쇼핑 카트 기능 구현: 웹 사이트에서 쇼핑 카트 기능을 구현할 때도 HTTP 세션을 사용할 수 있습니다. 사용자가 상품을 장바구니에 담으면, 서버는 해당 사용자의 세션에 상품 정보를 저장합니다. 이후 사용자가 쇼핑 카트를 확인하거나 주문을 완료할 때마다, 서버는 해당 세션에 저장된 정보를 확인하여 쇼핑 카트 정보를 제공합니다.

  3. 게시판에서 작성 중인 글 임시 저장: 웹 사이트에서 글을 작성할 때, 작성 중인 글을 임시로 저장하고 싶을 때 HTTP 세션을 사용할 수 있습니다. 사용자가 글을 작성하면, 서버는 해당 사용자의 세션에 작성 중인 글을 저장합니다. 이후 사용자가 다시 글 작성 페이지에 접속하면, 서버는 해당 세션에 저장된 글을 불러와서 사용자에게 제공합니다.

토큰

토큰은 인증을 위한 메커니즘 중 하나로, HTTP 요청에 대한 인증 정보를 전송하는 방식 중 하나입니다. 일반적으로 HTTP 토큰은 클라이언트가 서버에 인증 정보를 제공하기 위해, 특정 헤더에 토큰 값을 담아서 보냅니다. 서버는 이를 확인하여, 해당 클라이언트가 인증된 사용자인지를 판단합니다.

토큰 역사

토큰의 역사는 크게 세가지로 나눌수 있습니다.

  1. HTTP Token:
    HTTP Token 인증은 웹 보안이 주요 관심사가 아니었던 초기 웹에서 도입되었습니다. 사용자를 인증하기 위해 HTTP 요청 헤더에 토큰(보통 문자열)을 포함하는 간단한 인증 방식입니다. 서버는 토큰을 사전에 공유된 비밀과 비교하여 사용자의 신원을 확인합니다.
    HTTP Token은 간단하고 빠르게 구현할 수 있지만, 토큰이 노출될 경우 보안상의 문제가 발생합니다. 또한, 토큰이 각각의 요청마다 전송되므로 처리 부하가 크다는 문제가 있습니다.
    이러한 문제점으로 인하여 JWT Token이 나오게 되었습니다.

  2. JWT Token:
    JWT(JSON Web Token)은 2010년에 도입된 더욱 현대적이고 안전한 인증 메커니즘입니다. 사용자 클레임(claim)을 JSON 기반의 토큰 형식으로 전송하여 안전하고 간단하게 사용자를 인증하는 방식입니다. JWT 토큰은 디지털 서명을 사용하여 변조되지 않았음을 확인할 수 있습니다. 또한 보안을 강화하기 위해 암호화될 수 있습니다.

  3. OAuth Token:
    OAuth(Open Authorization)는 2006년에 개발된 인증 및 권한 부여 프로토콜입니다. 사용자가 자신의 자원(예: 소셜 미디어 계정)에 대한 제 3자 애플리케이션의 액세스를 비밀번호를 공유하지 않고 부여할 수 있도록 합니다. OAuth는 액세스 토큰을 사용하여 사용자를 인증하고 요청된 자원에 대한 액세스를 제공합니다. 이러한 액세스 토큰은 짧은 수명을 가질 수 있으며 사용자가 언제든지 취소할 수 있습니다.

토큰 종류

  1. JWT(Token) : JSON Web Token의 약자로, 사용자 정보를 JSON 형식으로 인코딩하여 생성합니다. 해당 정보는 서버에서 생성되어 클라이언트로 전달되며, 클라이언트는 이를 저장해두고 HTTP 요청시 해당 정보를 사용합니다. JWT는 정보가 인코딩되어 있기 때문에, 정보의 무결성을 보장할 수 있습니다.

  2. OAuth(Token) : OAuth는 사용자 인증을 위한 프로토콜로, HTTP 요청에 대한 인증 정보를 전송할 때 사용되는 토큰 기반의 인증 방식입니다. OAuth에서는 Access Token과 Refresh Token 두 가지 토큰을 사용합니다. Access Token은 일정 기간동안 유효하며, Refresh Token은 Access Token이 만료될 때마다 새로 발급받을 수 있는 토큰입니다.

JWT 토큰 프로세스

  1. 인증 요청: 클라이언트는 서버에 인증 요청을 보냅니다. 이때 요청 헤더에는 Authorization 필드가 추가됩니다.

  2. 토큰 발급: 서버는 클라이언트가 제공한 인증 정보를 확인하고, 인증이 성공하면 클라이언트에게 토큰을 발급합니다.

  3. 토큰 전달: 서버는 발급된 토큰을 클라이언트에게 전달합니다. 이때, 토큰은 일반적으로 HTTP 응답의 Authorization 헤더 필드나, 쿠키 등을 이용하여 클라이언트에게 전달됩니다.

  4. 토큰 저장: 클라이언트는 발급된 토큰을 안전한 장소에 저장합니다. 일반적으로는 브라우저의 localStorage, sessionStorage, 쿠키 등이 사용됩니다.

  5. 인증 요청 시 토큰 제공: 이후에 클라이언트가 서버에 인증 요청을 보낼 때마다, 저장된 토큰을 요청 헤더의 Authorization 필드에 포함시켜 보냅니다.

  6. 토큰 검증: 서버는 요청 헤더에 포함된 토큰을 검증하여, 클라이언트의 인증 상태를 확인합니다. 이때, 서버는 보통 JWT(JSON Web Token) 형태의 토큰을 사용하며, JWT는 서명(sign)과 암호화(encrypt)을 사용하여 안전하게 전달됩니다.

  7. 인증 처리: 토큰이 유효하다면, 서버는 클라이언트에게 요청된 작업을 수행하고, 결과를 응답합니다.

  8. 만료 처리: 만약 토큰이 만료되거나, 유효하지 않다면 서버는 클라이언트에게 새로운 토큰을 발급하도록 요청합니다. 클라이언트는 새로운 토큰을 받아 저장하고, 이를 이용하여 다음 인증 요청을 처리합니다.

JWT 토큰

JWT(JSON Web Token)란 인증에 필요한 정보들을 암호화시킨 JSON 토큰을 의미 합니다. 그리고 JWT 기반 인증은 JWT 토큰(Access Token)을 HTTP 헤더에 실어 서버가 클라이언트를 식별하는 방식 입니다.
JWT는 . 을 구분자로 나누어지는 세 가지 문자열의 조합 입니다. . 을 기준으로 좌측부터 Header, Payload, Signature를 의미합니다.

Header 에는 JWT 에서 사용할 타입과 해시 알고리즘의 종류가 담겨있으며, Payload 는 서버에서 첨부한 사용자 권한 정보와 데이터가 담겨있습니다. 마지막으로 Signature 에는 Header, Payload 를 Base64 URL-safe Encode 를 한 이후 Header 에 명시된 해시함수를 적용하고, 개인키(Private Key)로 서명한 전자서명이 담겨있습니다.

실제 디코딩된 JWT는 다음과 같은 json구조 입니다.

헤더

{
 "alg":"HS256",
 "typ:"JWT"
}

alg : 서명 암호화 알고리즘(ex: HMAC SHA256, RSA)
typ : 토큰 유형

payload

토큰에서 사용할 정보의 조각들인 Claim 이 담겨있습니다. (실제 JWT 를 통해서 알 수 있는 데이터)

즉, 서버와 클라이언트가 주고받는 시스템에서 실제로 사용될 정보에 대한 내용을 담고 있는 섹션 입니다.

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

key-value 형식으로 이루어진 한 쌍의 정보를 Claim이라고 칭한다.

Signature

시그니처에서 사용하는 알고리즘은 헤더에서 정의한 알고리즘 방식(alg)을 활용 합니다.
시그니처의 구조는 (헤더 + 페이로드)와 서버가 갖고 있는 유일한 key 값을 합친 것을 헤더에서 정의한 알고리즘으로 암호화를 합니다.

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  
  your-256-bit-secret

)

jwt 사용 예시

  1. 사용자 인증
    JWT는 사용자가 로그인할 때 사용됩니다. 클라이언트가 로그인 자격 증명을 서버에 보내면, 서버는 사용자의 정보를 확인하고 JWT를 생성합니다. 클라이언트는 이 JWT를 저장하고, 이후에 서버로 요청을 보낼 때마다 JWT를 포함시켜 보냅니다. 서버는 JWT를 검증하여 사용자를 인증합니다.

  2. API 보호
    API를 보호하기 위해 JWT를 사용할 수 있습니다. 클라이언트가 API 요청을 보낼 때마다 JWT를 포함시켜 보냅니다. 서버는 이 JWT를 검증하여 클라이언트의 권한을 확인하고 요청을 처리합니다.

  3. 사용자 권한 부여
    JWT는 사용자가 특정 작업을 수행할 수 있는 권한을 부여하는 데 사용됩니다. 서버는 JWT에 사용자의 권한 정보를 포함시키고, 클라이언트는 이 JWT를 검증하여 사용자의 권한을 확인하고 작업을 수행합니다.

실제 jwt를 이용한 로그인 로직 예시

    const jwt = require('jsonwebtoken');

    // JWT 생성 함수
    function createToken(user) {
      // JWT에 포함될 정보
      const payload = {
        id: user.id,
        email: user.email,
        name: user.name,
        // ...
      };

      // JWT 생성
      const token = jwt.sign(payload, 'secret_key', { expiresIn: '1h' });

      return token;
    }

    // JWT 검증 미들웨어
    function verifyToken(req, res, next) {
      // 헤더에서 JWT 추출
      const authHeader = req.headers.authorization;
      const token = authHeader && authHeader.split(' ')[1];

      if (!token) {
        // JWT가 없으면 인증 실패
        return res.status(401).json({ message: 'JWT가 없습니다.' });
      }

      // JWT 검증
      jwt.verify(token, 'secret_key', (err, user) => {
        if (err) {
          // 검증 실패
          return res.status(403).json({ message: 'JWT 검증 실패' });
        }

        // 검증 성공
        req.user = user;
        next();
      });
    }

    // 사용 예시
    app.post('/login', (req, res) => {
      // 이메일과 비밀번호를 검증하고 사용자 정보를 가져옴

      // JWT 생성
      const token = createToken(user);

      // JWT를 응답으로 보냄
      res.json({ token });
    });

    app.get('/protected', verifyToken, (req, res) => {
      // JWT 검증 미들웨어를 통과한 경우
      const user = req.user;

      // JWT에 담긴 사용자 정보를 이용하여 작업 수행

      res.json({ message: '인증 성공' });
    });

Oauth 2.0

OAuth 2.0은 인터넷에서 사용되는 인증 및 권한 부여 프로토콜 중 하나입니다. OAuth 2.0은 웹 API의 보안을 강화하고, 사용자 인증 절차를 간소화하여 서드파티 애플리케이션과의 연동을 쉽게 만듭니다.

Oauth 2.0 프로세스

  1. 클라이언트 애플리케이션이 인증을 요청합니다.
  2. 사용자는 인증 서버에 로그인합니다.
  3. 인증 서버는 사용자로부터 권한을 요청받은 클라이언트 애플리케이션을 확인하고, 사용자에게 권한 요청을 보여줍니다.
  4. 사용자가 권한 요청을 승인하면, 인증 서버는 클라이언트 애플리케이션에게 인증 코드(Authorization Code)를 발급합니다.
  5. 클라이언트 애플리케이션은 발급받은 인증 코드를 이용하여 액세스 토큰(Access Token)을 요청합니다.
  6. 인증 서버는 클라이언트 애플리케이션의 액세스 토큰 요청을 확인하고, 인증이 성공하면 액세스 토큰을 발급합니다.
  7. 클라이언트 애플리케이션은 발급받은 액세스 토큰을 이용하여 보호된 API에 요청합니다.
    보호된 API는 액세스 토큰의 유효성을 검증하고, 요청한 리소스에 대한 응답을 보냅니다.

Oauth 2.0 사용 예시

  • 소셜 로그인
    OAuth 2.0을 이용하여 소셜 로그인을 구현할 수 있습니다. 예를 들어, 페이스북, 트위터, 구글 등의 소셜 로그인을 지원하는 서비스에서는 OAuth 2.0을 이용하여 사용자가 해당 소셜 계정 정보를 입력하고 인증을 마친 후에 서비스를 이용할 수 있도록 합니다.

실제 Oauth2.0 사용한예시코드

const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const OAuth2Server = require('oauth2-server');
const OAuthModel = require('./oauth-model'); // 사용자 정의 모듈

// OAuth2Server 인스턴스 생성
const oauth = new OAuth2Server({
  model: OAuthModel, // 사용자 정의 모델 지정
  accessTokenLifetime: 60 * 60, // 액세스 토큰 유효 시간(1시간)
  allowBearerTokensInQueryString: true // URL 쿼리 문자열에서 액세스 토큰 사용 허용
});

// 요청 파서 미들웨어 설정
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

// 클라이언트 등록
app.post('/clients', async (req, res) => {
  const { client_id, client_secret } = req.body

캐시

캐시란 자주 사용하는 데이터나 값을 미리 복사해 놓는 임시 장소 입니다.

캐시 역사

HTTP 캐시의 역사는 HTTP 프로토콜의 초기 개발과 함께 시작되었습니다.

  1. HTTP/1.1에서는 캐시 기능이 크게 개선되었습니다. 캐시 제어에 사용되는 헤더는 다음과 같이 확장되었습니다.
  • Cache-Control: 캐시 동작을 지정합니다.
  • ETag: 리소스의 고유한 식별자를 제공합니다.
  • If-Modified-Since: 리소스가 마지막으로 변경된 이후에 변경되었는지 확인합니다.
  • If-None-Match: 리소스의 ETag 값과 일치하는지 확인합니다.
  1. HTTP/2에서는 캐시 기능은 기본적으로 유지되었지만, 성능과 보안이 개선되었습니다. HTTP/2는 캐시 데이터를 압축하여 전송하므로 대역폭을 절약할 수 있습니다. 또한 서버에서 전송되는 리소스에 대한 안전성을 높이기 위해 새로운 보안 메커니즘이 추가되었습니다.

  2. HTTP/3에서는 QUIC 프로토콜을 기반으로 한 새로운 프로토콜입니다. HTTP/3는 UDP를 사용하므로 캐시 기능은 프로토콜 수준에서 지원되지 않습니다. 그러나 캐시 기능은 여전히 HTTP/3를 지원하는 클라이언트와 서버에서 구현될 수 있습니다.

캐시의 없을때

  • 데이터가 변경되지 않아도 계속 네트워크를 통해서 데이터를 다운로드 받아야 한다.
  • 인터넷 네트워크는 매우 느리고 비싸다.
  • 브라우저 로딩 속도가 느리다.
  • 느린 사용자 경험



클라이언트에서 처음 서버측에 요청을 할때 서버의 응답결과를 캐시에 저장합니다. 그이후 다시 클라이언트에서 서버측에 요청할 때, 서버는 캐시 메커니즘을 사용하여 이전에 보낸 요청과 동일한 요청인지 확인합니다. 캐시 메커니즘을 사용할 때, 서버는 캐시에 저장된 데이터를 사용하여 응답을 생성하고, 이를 클라이언트에 반환합니다. 이 경우, 서버는 데이터가 변경되지 않은 경우에는 응답 본문(body)을 포함하지 않고 응답 헤더(header)만을 반환할 수 있습니다.

캐시 프로세스

  1. 클라이언트는 요청을 보냅니다.
  2. 서버는 요청에 대한 응답을 반환합니다.
  3. 클라이언트는 응답을 받고, 응답에 캐시 제어 헤더가 있는지 확인합니다.
  4. 캐시 제어 헤더가 있다면, 클라이언트는 응답을 캐시합니다.
  5. 클라이언트는 같은 요청을 다시 보낼 때, 이전에 캐시한 응답을 사용합니다.
  6. 캐시된 응답이 여전히 유효하다면, 클라이언트는 서버에 요청을 보내지 않고, 캐시된 응답을 사용합니다.
  7. 캐시된 응답이 만료되었다면, 클라이언트는 서버에 새로운 요청을 보내어 업데이트된 응답을 받습니다.

캐시 장점

  • 캐시 덕분에 캐시 가능 시간동안 네트워크를 사용하지 않아도 된다.
  • 비싼 네트워크 사용량을 줄일 수 있다.
  • 브라우저 로딩 속도가 매우 빠르다.
  • 빠른 사용자 경험

캐시 시간초과



  • 캐시 유효 시간이 초과하면, 서버를 통해 데이터를 다시 조회하고, 캐시를 갱신한다.
  • 이때 다시 네트워크 다운로드가 발생한다.

특징

  • 캐시 만료후에도 서버에서 데이터를 변경하지 않음
  • 데이터를 전송하는 대신에 저장해 두었던 캐시를 재사용 할 수 있다.
  • 클라이언트의 데이터와 서버의 데이터가 같다는 사실을 확인할 수 있는 방법 필요


캐시 정리

  • 캐시 유효 시간이 초과해도, 서버의 데이터가 갱신되지 않으면 304 Not Modified + 헤더 메타 정보만 응답(바디X)

  • 클라이언트는 서버가 보낸 응답 헤더 정보로 캐시의 메타 정보를 갱신

  • 클라이언트는 캐시에 저장되어 있는 데이터 재활용

  • 결과적으로 네트워크 다운로드가 발생하지만 용량이 적은 헤더 정보만 다운로드

  • 매우 실용적인 해결책

사용 예시

  • 웹 페이지에서 반복적으로 사용되는 정적인 리소스(CSS, JS, 이미지 등)에 대한 요청에 대해서는 캐시를 사용하여 서버의 부하를 줄일 수 있습니다.

  • HTTP 요청을 전송하는 시간을 줄이기 위해, 클라이언트가 이전에 요청한 데이터를 다시 사용할 수 있습니다.

  • 동일한 URL을 사용하는 다수의 요청에 대해, 서버는 첫 번째 요청에 대한 응답을 캐시에 저장하고, 이후의 요청에서는 캐시된 응답을 반환하여 서버의 부하를 줄일 수 있습니다.

  • 캐시된 데이터를 사용하면 네트워크 대역폭을 절약할 수 있습니다.

  • 빠른 응답 속도를 위해, 캐시된 데이터를 로컬 디스크나 메모리에 저장하여 다시 요청할 때 캐시된 데이터를 사용할 수 있습니다.

느낀점

restful에이어 쿠키,세션,토큰,캐시에 대해 공부해 보았는데, 공부해야되는 양이 굉장히 많아서 놀랐습니다. 정리하고 이해하는데 힘들었지만 재밌었습니다.

0개의 댓글