>  기사  >  웹 프론트엔드  >  JWT를 통한 인증을 통해 Node.js 및 WebSockets 기반 애플리케이션을 위한 사용자 정의 바이너리 프로토콜 개발

JWT를 통한 인증을 통해 Node.js 및 WebSockets 기반 애플리케이션을 위한 사용자 정의 바이너리 프로토콜 개발

WBOY
WBOY원래의
2024-08-26 21:47:32520검색

소개

효율적이고 안전한 애플리케이션을 개발하려면 신중한 API뿐만 아니라 올바른 데이터 전송 프로토콜 선택도 필요합니다. 웹 애플리케이션은 일반적으로 JSON 또는 XML과 같은 텍스트 기반 형식을 사용하지만 최소 대기 시간과 낮은 데이터 전송량이 요구되는 고성능 시스템의 경우 바이너리 프로토콜을 사용하는 것이 유리합니다. 이 기사에서는 Node.jsWebSockets 기반 애플리케이션용 사용자 정의 바이너리 프로토콜을 개발하고, JWT를 통해 인증을 추가하는 방법을 살펴보겠습니다. 다른 데이터 형식에 비해 바이너리 프로토콜의 장점을 살펴보세요.

Developing a custom binary protocol for Node.js and WebSockets based applications with authorization via JWT

왜 바이너리 프로토콜인가요?

바이너리 프로토콜의 장점:

  • 효율성: 바이너리 프로토콜은 텍스트 기반 형식(예: JSON)보다 더 컴팩트합니다. 이를 통해 데이터를 보다 압축된 형식으로 전송할 수 있으므로 전송되는 트래픽 양이 줄어듭니다.

  • 성능: 데이터가 적고 텍스트 형식을 구문 분석할 필요가 없는 바이너리 프로토콜은 클라이언트와 서버 측의 리소스를 절약합니다.

  • 보안: 바이너리 데이터는 텍스트 데이터에 비해 즉석에서 분석하기가 어렵기 때문에 바이너리 프로토콜이 공격에 덜 취약합니다.

  • 유연성: 바이너리 프로토콜에서는 특정 데이터 유형(예: 부동 소수점 숫자, 문자열, 바이트 배열 등)을 수용하도록 데이터 형식을 더욱 정밀하게 제어할 수 있습니다.

시스템 아키텍처:

다음 구성 요소로 구성된 시스템을 개발합니다.

  • 클라이언트와 통신하기 위해 WebSocket을 사용하는 Node.js의 서버입니다.

  • 서버에 연결하고 바이너리 프로토콜을 사용하여 데이터를 전송하는 JavaScript 클라이언트입니다.

  • JWT(JSON 웹 토큰)를 사용하여 인증하여 클라이언트를 서버에 안전하게 연결합니다.

Node.js에서 서버 구현

종속성 설치

먼저 필요한 종속성을 설치해 보겠습니다.

npm init -y
npm install ws jsonwebtoken

ws는 서버측에서 WebSocket 작업을 위한 라이브러리이고, jsonwebtoken은 JWT 작업을 위한 라이브러리입니다.

간단한 서버 코드:

const WebSocket = require('ws');
const jwt = require('jsonwebtoken');

// Our JWT Secret Key
const SECRET_KEY = 'your_secret_key';

// Create a new WebSocket Server
const wss = new WebSocket.Server({ port: 8080 });

// JWT Verification Function
function verifyJWT(token) {
    try {
        return jwt.verify(token, SECRET_KEY);
    } catch (e) {
        return null;
    }
}

// WebSocket Connection
wss.on('connection', (ws, req) => {
    // Get Token from Headers
    const token = req.url.split('token=')[1];
    const user = verifyJWT(token);

    // User is not Verified
    if (!user) {
        ws.close(4001, 'Unauthorized');
        return;
    }

    console.log(`User ${user.username} connected`);

    ws.on('message', (message) => {
        // Here we looking at message type. It must be a binary buffer
        if (message instanceof Buffer) {
            // Work with binary message
            const messageType = message.readUInt8(0); // First Byte - Message Type

            if (messageType === 1) { // If Message type is 1
                const textLength = message.readUInt16BE(1); // Get Message Length
                const text = message.toString('utf-8', 3, 3 + textLength);
                console.log(`Received message from ${user.username}: ${text}`);
            } else if(messageType === 2) {
                // Work with your message types
            }
        }
    });

    ws.on('close', () => {
        console.log(`User ${user.username} disconnected`);
    });
});

console.log('WebSocket server started on ws://localhost:8080');

코드 설명:

  • JWT 인증: 서버는 연결 시 클라이언트가 전달한 JWT 토큰을 확인합니다. 토큰이 유효하지 않은 경우 서버는 인증 오류로 연결을 종료합니다.

  • 바이너리 데이터 처리: 이 예에서는 클라이언트가 바이너리 데이터를 전송한다고 가정합니다. 서버는 데이터를 바이트 단위로 읽어 메시지를 구문 분석합니다. 예를 들어, 메시지의 첫 번째 바이트를 메시지 유형으로 사용할 수 있고 그 뒤에 메시지 길이와 데이터 자체를 사용할 수 있습니다.

  • WebSocket 서버: ws 라이브러리는 연결과 메시지를 관리하는 데 사용됩니다.

클라이언트 구현

클라이언트 코드

클라이언트 구현을 위해 순수 JavaScript를 사용합니다.

// Create Socket with our JWT Token
const socket = new WebSocket('ws://localhost:8080?token=your_jwt_token');

// Open Connection
socket.addEventListener('open', () => {
    console.log('Connected to server');

    // Binary Message example
    const message = "Hello, Binary World!";
    const buffer = new ArrayBuffer(3 + message.length);
    const view = new DataView(buffer);

    view.setUint8(0, 1); // Message type
    view.setUint16(1, message.length); // Message length
    for (let i = 0; i < message.length; i++) {
        view.setUint8(3 + i, message.charCodeAt(i));
    }

    socket.send(buffer);
});

// Get Response from server
socket.addEventListener('message', (event) => {
    if (event.data instanceof Blob) {
        event.data.arrayBuffer().then(buffer => {
            const view = new DataView(buffer);
            const messageType = view.getUint8(0);

            if (messageType === 1) { // Type 1 - Text Message
                const textLength = view.getUint16(1);
                const text = String.fromCharCode(...new Uint8Array(buffer.slice(3, 3 + textLength)));
                console.log(`Received message: ${text}`);
            }
        });
    }
});

// Close Connection
socket.addEventListener('close', () => {
    console.log('Disconnected from server');
});

코드 설명:

  • 서버 연결: 클라이언트는 요청 문자열을 통해 JWT 토큰을 전달하여 WebSocket 서버에 연결합니다.

  • 바이너리 데이터 전송: 바이너리 데이터를 전송하기 위해 메시지 유형과 텍스트 데이터가 기록되는 ArrayBuffer가 생성됩니다.

  • 메시지 수신: 클라이언트는 서버에서 바이너리 데이터를 예상하고 DataView를 사용하여 이를 구문 분석하여 바이트를 읽습니다.

JWT 토큰 생성 및 검증

서버 측에서 JWT 토큰을 생성하는 예:

const jwt = require('jsonwebtoken');

// Secret Key
const SECRET_KEY = 'your_secret_key';

// Example of JWT Token Generation
const token = jwt.sign({ username: 'user1' }, SECRET_KEY, { expiresIn: '1h' });
console.log(token);

이 토큰은 클라이언트 연결에 사용될 수 있습니다.

결론

WebSocketJWT를 통한 인증과 함께 바이너리 프로토콜을 사용하면 클라이언트-서버 통신을 위한 효율적이고 안전한 시스템이 가능합니다. 바이너리 프로토콜은 구현이 복잡함에도 불구하고 상당한 성능과 데이터 감소 이점을 제공합니다. 지연 시간과 네트워크 활용도를 최소화하는 것이 중요한 로드가 많고 리소스 집약적인 애플리케이션에 특히 적합합니다.

이러한 접근 방식은 게임 개발, 실시간 시스템, 금융 애플리케이션 및 고성능과 안정성이 요구되는 기타 시스템에 유용할 수 있습니다.

물론 읽어주셔서 감사합니다.


또한 튜토리얼과 기사 작성을 지원하고 프로젝트에 미리 준비된 솔루션을 볼 수도 있습니다.

나의 디스코드 | 내 블로그 | 내 GitHub | 맥주 사주세요

BTC: bc1qef2d34r4xkrm48zknjdjt7c0ea92ay9m2a7q55

ETH: 0x1112a2Ef850711DF4dE9c432376F255f416ef5d0

위 내용은 JWT를 통한 인증을 통해 Node.js 및 WebSockets 기반 애플리케이션을 위한 사용자 정의 바이너리 프로토콜 개발의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.