본문 바로가기

ChatGPT/Backend

[Typescript][Express] Server-Sent Events (SSE)로 실시간 웹 애플리케이션 구현하기

반응형

Server-Sent Events (SSE)란 무엇인가?

Server-Sent Events (SSE)는 서버에서 클라이언트로 실시간 이벤트를 전송하는 기술입니다. 웹 애플리케이션에서 서버와 클라이언트 간의 양방향 통신을 위해 사용되며, 웹소켓(WebSocket)과 마찬가지로 실시간 통신을 지원합니다. 하지만, WebSocket과 달리 SSE는 일방향 통신 방식으로, 서버에서 클라이언트로만 데이터를 전송합니다.

SSE는 HTML5에서 표준으로 지원되며, 다른 기술과 함께 사용하여 실시간 웹 애플리케이션을 구현할 수 있습니다.

SSE와 WebSocket의 차이점

SSE와 WebSocket은 모두 실시간 통신을 지원하지만, 두 기술에는 몇 가지 차이점이 있습니다.

먼저, SSE는 일방向 통신 방식으로, 서버에서 클라이언트로만 데이터를 전송합니다. 반면 WebSocket은 양방향 통신 방식으로, 서버와 클라이언트 간의 양방향 통신이 가능합니다.

또한, SSE는 HTTP 프로토콜을 기반으로 하며, 서버와 클라이언트 간의 연결을 계속 유지하면서 데이터를 전송합니다. 반면 WebSocket은 HTTP를 사용하여 연결을 설정한 후, 이후에는 별도의 프로토콜을 사용하여 데이터를 전송합니다.

또한, SSE는 HTTP 스펙에 맞게 작동하며, 기존의 HTTP 인프라를 활용하여 구현이 가능합니다. 반면 WebSocket은 새로운 프로토콜을 사용하기 때문에, 일부 환경에서는 추가적인 구현 작업이 필요할 수 있습니다.

SSE가 유용한 경우

SSE는 일반적으로 다음과 같은 경우에 유용합니다.

  • 실시간 정보를 제공하는 경우 (주식 가격, 날씨 등)
  • 실시간 알림을 제공하는 경우 (메시지, 이메일, 일정 등)
  • 팀 협업 툴에서 실시간 변경 사항을 제공하는 경우

다음으로, SSE의 구현 방법에 대해 알아보겠습니다.

SSE의 구현 방법

SSE 프로토콜

SSE 프로토콜은 HTTP 프로토콜을 기반으로 하며, 클라이언트와 서버 간에 일방적으로 데이터를 전송합니다. 클라이언트는 HTTP GET 요청을 보내고, 서버는 이에 대한 응답으로 SSE 메시지를 전송합니다. SSE 메시지는 여러 개의 이벤트로 구성됩니다.

SSE 요청과 응답

SSE 요청은 HTTP GET 요청을 사용합니다. 클라이언트는 서버에 HTTP GET 요청을 보내면, 서버는 이에 대한 응답으로 SSE 이벤트를 전송합니다.

SSE 요청에서는 Accept 헤더를 text/event-stream으로 설정합니다. Cache-Control 헤더는 no-cache로 설정하고, Connection 헤더는 keep-alive로 설정합니다.

SSE 응답에서는 Content-Type 헤더를 text/event-stream으로 설정하고, Cache-Control 헤더는 no-cache로 설정합니다. Connection 헤더는 keep-alive로 설정하며, SSE 이벤트를 전송하기 위한 추가적인 헤더를 포함시킬 수 있습니다.

SSE 이벤트의 구성

SSE 이벤트는 event, data, id 등의 필드를 포함할 수 있습니다. event 필드는 이벤트의 이름을 지정하며, data 필드는 이벤트에 대한 데이터를 전송합니다. id 필드는 이벤트의 ID를 지정합니다.

예를 들어, 다음과 같은 SSE 이벤트를 전송할 수 있습니다.

event: update
data: {"time": "2023-04-20T12:34:56Z", "message": "Hello, world!"}

위 이벤트는 update라는 이벤트 이름을 가지며, {"time": "2023-04-20T12:34:56Z", "message": "Hello, world!"}라는 데이터를 전송합니다.

SSE 이벤트의 전송

SSE 이벤트는 일정한 주기로 전송됩니다. 서버는 keep-alive 옵션을 사용하여 연결을 유지하고, 일정한 주기로 이벤트를 전송합니다. 이를 위해 서버에서는 주기적으로 이벤트를 생성해야 합니다.

예를 들어, 다음과 같이 서버에서 SSE 이벤트를 생성하여 클라이언트에 전송할 수 있습니다.

import express from 'express';

const app = express();

app.get('/stream', (req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
  });

  setInterval(() => {
    const data = JSON.stringify({
      message: 'Hello, world!',
      timestamp: new Date().toISOString(),
    });

    const event = 'update';

    const id = new Date().getTime();

    res.write(`event: ${event}\n`);
    res.write(`id: ${id}\n`);
    res.write(`data: ${data}\n\n`);
  }, 1000);
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

위 코드에서는 /stream 경로로 HTTP GET 요청이 들어오면, text/event-stream 형식의 SSE 이벤트를 전송합니다. setInterval 함수를 사용하여 1초마다 이벤트를 생성하고, res.write 함수를 사용하여 이벤트를 전송합니다. 이벤트의 구성은 앞서 설명한대로 event, data, id 등의 필드를 사용하여 구성합니다.

SSE의 보안

SSE의 보안 이슈

SSE는 서버에서 클라이언트로 데이터를 전송하는 방식으로 동작합니다. 이때, 데이터 전송 과정에서 보안 이슈가 발생할 수 있습니다. 대표적인 보안 이슈는 다음과 같습니다.

  1. XSS(Cross-Site Scripting) 공격: 클라이언트에서 수신한 데이터가 악성 스크립트를 포함하는 경우, 클라이언트 측에서 이를 실행할 수 있습니다.
  2. CSRF(Cross-Site Request Forgery) 공격: SSE를 통해 전송된 데이터가 인증 정보를 포함하는 경우, 이를 이용하여 CSRF 공격을 수행할 수 있습니다.

따라서, SSE를 사용할 때는 보안 이슈를 고려하여 적절한 대응 방안을 마련해야 합니다.

SSE 보안 대응 방안

SSE를 보안적으로 안전하게 사용하기 위해서는 다음과 같은 대응 방안을 마련해야 합니다.

  1. 데이터 필터링: 서버에서 전송되는 데이터에 대해 필터링을 수행하여 악성 스크립트가 포함된 데이터를 제거합니다.
  2. HTTPS 사용: SSE를 사용할 때는 HTTPS를 사용하여 데이터 전송 과정에서 암호화를 수행합니다.
  3. 쿠키 사용 제한: SSE를 통해 전송되는 데이터에 인증 정보가 포함된 경우, 이를 쿠키에 저장하지 않도록 합니다.
  4. 동일 출처 정책: SSE를 사용할 때는 동일 출처 정책을 적용하여, 다른 출처에서의 SSE 연결을 차단합니다.
  5. CORS 설정: SSE를 사용할 때는 CORS(Cross-Origin Resource Sharing) 설정을 통해 다른 출처에서의 SSE 연결을 차단합니다.

이러한 대응 방안을 마련하여 SSE를 보안적으로 안전하게 사용할 수 있습니다.

이상으로 SSE의 보안에 대해 알아보았습니다.

마무리

이상으로 Server-Sent Events(SSE)에 대해서 알아보았습니다. SSE는 웹 애플리케이션에서 실시간 데이터를 전송하기 위한 효과적인 방법 중 하나입니다. SSE를 사용하면 브라우저는 서버로부터 실시간 데이터를 수신하고, 이를 통해 다양한 기능을 구현할 수 있습니다.

SSE를 구현하기 위해서는 서버 측에서 text/event-stream MIME 타입의 HTTP 응답을 생성하고, 클라이언트는 이를 EventSource 객체를 사용하여 수신합니다. 이를 통해 클라이언트는 서버로부터 실시간 데이터를 수신할 수 있습니다.

또한, SSE를 사용할 때는 보안 이슈를 고려하여 대응 방안을 마련해야 합니다. 데이터 필터링, HTTPS 사용, 쿠키 사용 제한, 동일 출처 정책, CORS 설정 등의 방법을 사용하여 SSE를 보안적으로 안전하게 사용할 수 있습니다.

SSE는 웹 애플리케이션에서 실시간 데이터 전송에 효과적인 방법 중 하나입니다. 앞서 설명한 내용을 참고하여, SSE를 사용하여 다양한 기능을 구현해 보시기 바랍니다.

 

이글은 ChatGPT의 도움을 받아 작성되었습니다.

반응형