ホームページ  >  記事  >  ウェブフロントエンド  >  JWT による認証を使用した Node.js および WebSocket ベースのアプリケーション用のカスタム バイナリ プロトコルの開発

JWT による認証を使用した Node.js および WebSocket ベースのアプリケーション用のカスタム バイナリ プロトコルの開発

WBOY
WBOYオリジナル
2024-08-26 21:47:32592ブラウズ

導入

効率的で安全なアプリケーションを開発するには、よく考えられた API だけでなく、データ転送プロトコルの正しい選択も必要です。 Web アプリケーションは通常、JSONXML などのテキストベースの形式を使用しますが、最小限の遅延 と低いデータ転送量を必要とする高性能システムの場合、バイナリプロトコルを使用すると有利です。この記事では、Node.js および WebSockets ベースのアプリケーション 用のカスタム バイナリ プロトコルを開発し、JWT 経由で承認を追加する方法を説明します。他のデータ形式と比較したバイナリ プロトコルの利点を探ります。

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

なぜバイナリプロトコルなのか?

バイナリプロトコルの利点:

  • 効率: バイナリ プロトコルは、テキストベースの形式 (JSON など) よりもコンパクトです。データをより圧縮された形式で送信できるため、送信されるトラフィックの量が削減されます。

  • パフォーマンス: データが少なく、テキスト形式を解析する必要がないため、バイナリ プロトコルはクライアント側とサーバー側のリソースを節約します。

  • セキュリティ: バイナリ データはテキスト データに比べてその場で分析することが難しいため、バイナリ プロトコルは攻撃に対して脆弱になりません。

  • 柔軟性: バイナリ プロトコルでは、特定のデータ型 (浮動小数点数、文字列、バイト配列など) に対応するためにデータ形式をより正確に制御できます。

システムアーキテクチャ:

次のコンポーネントで構成されるシステムを開発します:

  • クライアントとの通信に WebSocket を使用する Node.js 上のサーバー。

  • サーバーに接続し、バイナリ プロトコルを使用してデータを転送する JavaScript クライアント

  • クライアントをサーバーに安全に接続するための JWT (JSON Web トークン) を使用した認証。

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);

このトークンはクライアントの接続に使用できます。

結論

WebSocket および JWT による認証と組み合わせてバイナリ プロトコルを使用すると、クライアント/サーバー通信用の効率的で安全なシステムが可能になります。バイナリ プロトコルは、実装が複雑であるにもかかわらず、パフォーマンスとデータ削減に大きなメリットをもたらします。これらは、待ち時間とネットワーク使用率を最小限に抑えることが重要な、負荷が高くリソースを大量に消費するアプリケーションに特に適しています。

このアプローチは、ゲーム開発、リアルタイム システム、金融アプリケーション、および高いパフォーマンスと信頼性を必要とするその他のシステムに役立ちます。

そしてもちろん、読んでいただきありがとうございます。


チュートリアルや記事の作成をサポートしたり、プロジェクト用の既製のソリューションを確認したりすることもできます:

私の不和 | 私のブログ | 私の GitHub | ビールを買ってきてください

BTC: bc1qef2d34r4xkrm48zknjdjt7c0ea92ay9m2a7q55

ETH: 0x1112a2Ef850711DF4dE9c432376F255f416ef5d0

以上がJWT による認証を使用した Node.js および WebSocket ベースのアプリケーション用のカスタム バイナリ プロトコルの開発の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。