NestJS एंटरप्राइज़ बैकएंड API · पाठ

Socket Connections का प्रमाणीकरण और सुरक्षा

सुरक्षित realtime access के लिए handshake और message events पर guards तथा token verification लागू कीजिए।

पाठ 2, कुल 4 में से13 चरण

Socket Connections का प्रमाणीकरण और सुरक्षा, CoddyKit पर NestJS एंटरप्राइज़ बैकएंड API का एक निःशुल्क पाठ है। यह 4 में से 2वाँ पाठ है। आप नीचे पूरा पाठ निःशुल्क पढ़ सकते हैं—फिर अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर के साथ ब्राउज़र में इसका व्यावहारिक अभ्यास कर सकते हैं। यह NestJS एंटरप्राइज़ बैकएंड API सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। NestJS एंटरप्राइज़ बैकएंड API पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

सॉकेट के लिए अपना प्रमाणीकरण क्यों आवश्यक है

NestJS में HTTP रूट middleware और guards द्वारा सुरक्षित किए जाते हैं, जो हर अनुरोध पर Authorization हेडर पढ़ते हैं। WebSockets अलग होते हैं: क्लाइंट हैंडशेक के दौरान एक लंबे समय तक खुला कनेक्शन बनाता है और फिर उसी पर कई संदेशों का आदान-प्रदान करता है।

  • आप कनेक्शन के समय एक बार प्रमाणीकरण करते हैं, हर संदेश पर नहीं।
  • सॉकेट कई मिनट या घंटों तक खुला रह सकता है, इसलिए सत्र के बीच में समाप्त होने वाला टोकन वास्तविक चिंता है।
  • मानक HTTP guards WebSocket घटनाओं पर अपने-आप नहीं चलते।

यह पाठ दिखाता है कि हैंडशेक के दौरान टोकन का सत्यापन कैसे करें, उपयोगकर्ता को socket से कैसे जोड़ें और सुरक्षित रीयल-टाइम पहुँच के लिए अलग-अलग संदेश घटनाओं को कैसे सुरक्षित करें।

हैंडशेक में टोकन कहाँ रहता है

ब्राउज़र का WebSocket कस्टम हेडर सेट नहीं कर सकता, इसलिए क्लाइंट Socket.IO हैंडशेक के दौरान टोकन को तीन में से किसी एक स्थान पर भेजते हैं:

  • handshake.auth.token — आधुनिक और पसंदीदा स्थान (क्लाइंट के auth विकल्प से सेट किया जाता है)।
  • handshake.headers.authorization — मूल हेडर उपलब्ध होने पर काम करता है।
  • handshake.query.token — वैकल्पिक उपाय, लेकिन टोकन server या प्रॉक्सी के लॉग में आ जाते हैं, इसलिए इससे बचें।

एक छोटा सहायक फ़ंक्शन टोकन निकालने की प्रक्रिया को एक जगह रखता है, ताकि हर guard और जीवनचक्र हुक टोकन को एक ही तरीके से पढ़े।

import { Socket } from 'socket.io';

export function extractToken(client: Socket): string | null {
  const auth = client.handshake.auth?.token;
  if (typeof auth === 'string') return auth;

  const header = client.handshake.headers?.authorization;
  if (typeof header === 'string' && header.startsWith('Bearer ')) {
    return header.slice(7);
  }

  return null;
}

handleConnection के साथ कनेक्शन पर सत्यापन

प्रमाणीकरण के लिए सबसे साफ़ स्थान gateway का handleConnection जीवनचक्र हुक है। यह क्लाइंट के कनेक्ट होते ही चलता है। यदि टोकन मौजूद नहीं है या अमान्य है, तो client.disconnect() कॉल करें, ताकि socket किसी भी रूम या घटना में भाग न ले सके।

सफल होने पर डिकोड किए गए उपयोगकर्ता को client.data में जोड़ें — यह प्रत्येक socket के लिए अलग संग्रह है, जो कनेक्शन की पूरी अवधि तक बना रहता है और बाद के हर घटना हैंडलर में पढ़ा जा सकता है।

import { OnGatewayConnection, WebSocketGateway } from '@nestjs/websockets';
import { JwtService } from '@nestjs/jwt';
import { Socket } from 'socket.io';
import { extractToken } from './extract-token';

@WebSocketGateway({ cors: true })
export class ChatGateway implements OnGatewayConnection {
  constructor(private readonly jwt: JwtService) {}

  async handleConnection(client: Socket) {
    try {
      const token = extractToken(client);
      if (!token) throw new Error('No token');
      const payload = await this.jwt.verifyAsync(token);
      client.data.user = { id: payload.sub, role: payload.role };
    } catch {
      client.disconnect(true);
    }
  }
}

प्रमाणित उपयोगकर्ता का मॉडल बनाना

client.data.user को बिना प्रकार वाली वस्तु के रूप में संग्रहीत करने से आगे चलकर टाइपिंग की गलतियाँ हो सकती हैं। एक छोटा interface और प्रकार-सहित सहायक फ़ंक्शन परिभाषित करें, ताकि हर हैंडलर user.id और user.role को पूर्ण IntelliSense और संकलन-समय सुरक्षा के साथ पढ़ सके।

यह वही JWT payload पैटर्न है जिसका उपयोग आप HTTP रूट के लिए करते हैं, जिससे दोनों ट्रांसपोर्ट में प्राधिकरण का तर्क एकसमान रहता है।

export interface SocketUser {
  id: string;
  role: 'admin' | 'member' | 'guest';
}

export interface JwtPayload {
  sub: string;
  role: SocketUser['role'];
  exp: number;
}

export function toSocketUser(payload: JwtPayload): SocketUser {
  return { id: payload.sub, role: payload.role };
}

// Demo: a decoded token becomes a typed user
const payload: JwtPayload = { sub: 'u_42', role: 'member', exp: 1893456000 };
const user = toSocketUser(payload);
console.log(`${user.id} connected as ${user.role}`);

अलग-अलग संदेश घटनाओं को सुरक्षित करना

कनेक्शन-समय का प्रमाणीकरण यह सिद्ध करता है कि उपयोगकर्ता कौन है, लेकिन कुछ घटनाओं में प्राधिकरण जाँच भी आवश्यक होती है — उदाहरण के लिए, केवल व्यवस्थापक ही सिस्टम संदेश प्रसारित कर सकें। NestJS guards WebSocket घटनाओं पर भी काम करते हैं; आपको बस execution context से socket पढ़ना होता है।

किसी guard के भीतर context को ws पर बदलें, client प्राप्त करें और handleConnection द्वारा भरे गए client.data.user की जाँच करें।

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { WsException } from '@nestjs/websockets';
import { Socket } from 'socket.io';

@Injectable()
export class WsAuthGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const client = context.switchToWs().getClient<Socket>();
    const user = client.data.user;
    if (!user) {
      throw new WsException('Unauthorized');
    }
    return true;
  }
}

मेटाडेटा के साथ भूमिका-आधारित guards

किसी घटना को कुछ निश्चित भूमिकाओं तक सीमित करने के लिए एक कस्टम decorator (जो आवश्यक भूमिकाओं को metadata के रूप में संग्रहीत करता है) को ऐसे guard के साथ मिलाएँ जो उन्हें Reflector के माध्यम से पढ़ता है। यह HTTP के @Roles() पैटर्न जैसा ही है, इसलिए आपकी टीम एक ही मानसिक मॉडल सीखती है।

जब जुड़े हुए उपयोगकर्ता के पास आवश्यक भूमिका नहीं होती, तो guard WsException के साथ घटना को अस्वीकार कर देता है — संदेश हैंडलर चलता ही नहीं।

import { SetMetadata } from '@nestjs/common';
export const WsRoles = (...roles: string[]) => SetMetadata('ws_roles', roles);

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { WsException } from '@nestjs/websockets';
import { Socket } from 'socket.io';

@Injectable()
export class WsRolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const required = this.reflector.get<string[]>('ws_roles', context.getHandler());
    if (!required?.length) return true;
    const user = context.switchToWs().getClient<Socket>().data.user;
    if (!user || !required.includes(user.role)) {
      throw new WsException('Forbidden');
    }
    return true;
  }
}

Subscribe handlers पर guards लागू करना

संदेश हैंडलर पर @UseGuards() के साथ guards लगाएँ, ठीक controller रूट की तरह। मूल प्रमाणीकरण guard को roles guard के साथ क्रम में लगाएँ और हैंडलर को आवश्यक भूमिकाओं से सजाएँ।

Guards घोषणा के क्रम में चलते हैं, इसलिए पहले कम लागत वाली प्रमाणीकरण जाँच और उसके बाद भूमिका जाँच रखें।

import { SubscribeMessage, WebSocketGateway, MessageBody } from '@nestjs/websockets';
import { UseGuards } from '@nestjs/common';
import { WsAuthGuard } from './ws-auth.guard';
import { WsRolesGuard } from './ws-roles.guard';
import { WsRoles } from './ws-roles.decorator';

@WebSocketGateway()
export class AdminGateway {
  @UseGuards(WsAuthGuard, WsRolesGuard)
  @WsRoles('admin')
  @SubscribeMessage('broadcast')
  handleBroadcast(@MessageBody() text: string) {
    return { event: 'broadcast', data: text };
  }
}

केवल guards हैंडशेक को क्यों नहीं पकड़ते

एक सूक्ष्म समस्या: डिफ़ॉल्ट रूप से WebSocket guard प्रारंभिक कनेक्शन पर नहीं, बल्कि संदेश घटनाओं पर चलता है। यदि आप केवल @UseGuards पर निर्भर रहते हैं और handleConnection छोड़ देते हैं, तो कोई अप्रमाणित क्लाइंट फिर भी socket खोलकर आपके server पर निष्क्रिय बैठा रह सकता है।

  • अप्रमाणित sockets को प्रवेश द्वार पर अस्वीकार करने के लिए handleConnection का उपयोग करें।
  • हर कार्रवाई के सूक्ष्म स्तर के प्राधिकरण के लिए घटना guards का उपयोग करें।

ये दोनों परतें एक-दूसरे की पूरक हैं: एक प्रवेश नियंत्रित करती है और दूसरी कार्रवाइयाँ।

क्लाइंट को त्रुटियाँ साफ़-साफ़ दिखाना

जब कोई guard WsException उत्पन्न करता है, तो NestJS कनेक्शन को बंद करने के बजाय उस क्लाइंट को exception घटना भेजता है। payload का आकार तय करने के लिए WsExceptionFilter जोड़ें, ताकि frontend को ऐसा अनुमानित त्रुटि ऑब्जेक्ट मिले जिसे वह उपयोगकर्ता को दिखा सके।

import { ArgumentsHost, Catch } from '@nestjs/common';
import { BaseWsExceptionFilter, WsException } from '@nestjs/websockets';
import { Socket } from 'socket.io';

@Catch(WsException)
export class WsErrorFilter extends BaseWsExceptionFilter {
  catch(exception: WsException, host: ArgumentsHost) {
    const client = host.switchToWs().getClient<Socket>();
    client.emit('error', {
      message: exception.getError(),
      timestamp: new Date().toISOString(),
    });
  }
}

सक्रिय socket पर टोकन की समय-सीमा समाप्ति संभालना

एक घंटे पहले प्रमाणित किया गया कनेक्शन अब समाप्त हो चुका टोकन रख सकता है। दो सामान्य रणनीतियाँ हैं:

  • संवेदनशील घटना पर फिर से सत्यापन — मूल टोकन को client.data.token में रखें और महत्वपूर्ण कार्रवाइयों के लिए guard के भीतर फिर से verifyAsync कॉल करें।
  • नियत अंतराल पर पुनःसत्यापन — server का एक अंतराल प्रत्येक socket के टोकन exp की जाँच करता है और समाप्त हो चुके sockets को डिस्कनेक्ट कर देता है।

यह छोटा शुद्ध फ़ंक्शन दोनों में से किसी भी उपाय के केंद्र में होने वाली समय-सीमा जाँच दिखाता है।

interface TokenInfo {
  exp: number; // unix seconds
}

function isExpired(token: TokenInfo, nowSeconds: number): boolean {
  return token.exp <= nowSeconds;
}

const now = 1_700_000_000;
console.log(isExpired({ exp: 1_699_999_000 }, now)); // true  -> disconnect
console.log(isExpired({ exp: 1_700_500_000 }, now)); // false -> keep open

मॉड्यूल में सब कुछ जोड़ना

Reflector या JwtService जैसी सेवाएँ इंजेक्ट करने वाले guards को Nest के DI द्वारा हल किया जा सकना चाहिए। चूँकि gateway और उसके guards एक ही मॉड्यूल में रहते हैं, JwtModule पंजीकृत करें और gateway प्रदान करें; @UseGuards में संदर्भित होने पर Nest guards के उदाहरण स्वयं बनाता है।

यदि हर घटना का डिफ़ॉल्ट रूप से प्रमाणीकरण होना चाहिए, तो आप sockets के लिए APP_GUARD के साथ auth guard को वैश्विक रूप से भी पंजीकृत कर सकते हैं।

import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { APP_GUARD } from '@nestjs/core';
import { ChatGateway } from './chat.gateway';
import { WsAuthGuard } from './ws-auth.guard';

@Module({
  imports: [
    JwtModule.register({ secret: process.env.JWT_SECRET }),
  ],
  providers: [
    ChatGateway,
    { provide: APP_GUARD, useClass: WsAuthGuard },
  ],
})
export class RealtimeModule {}

त्वरित जाँच: कनेक्शन बनाम घटना प्रमाणीकरण

आप चाहते हैं कि (1) अप्रमाणित क्लाइंट कभी socket खोल ही न सकें और (2) केवल admin उपयोगकर्ता ही broadcast घटना emit कर सकें। दोनों उद्देश्यों को सही ढंग से पूरा करने वाला संयोजन कौन-सा है?

पुनरावलोकन: रीयल-टाइम कनेक्शन सुरक्षित करना

अब आपके पास NestJS WebSocket gateways को सुरक्षित करने का एक पूर्ण, परतदार तरीका है:

  • निकालें — handshake.auth, हेडर या query से टोकन को एकसमान तरीके से निकालें।
  • प्रवेश द्वार पर प्रमाणित करें — handleConnection में अमान्य क्लाइंट को डिस्कनेक्ट करें और उपयोगकर्ता को client.data में जोड़ें।
  • प्रत्येक घटना पर प्राधिकरण दें — ऐसे guards का उपयोग करें जो ws context पर स्विच करते हैं, जिनमें Reflector के माध्यम से भूमिका जाँच और @WsRoles decorator शामिल हैं।
  • त्रुटियों की सूचना दें — WsException filter के माध्यम से, और समय-सीमा समाप्ति संभालें — फिर से सत्यापन या नियत अंतराल पर जाँच के द्वारा।

कनेक्शन प्रमाणीकरण प्रवेश को नियंत्रित करता है; घटना guards कार्रवाइयों को नियंत्रित करते हैं — साथ मिलकर वे आपके रीयल-टाइम सिस्टम को सुरक्षित रखते हैं।

शुरुआत निःशुल्क

एआई शिक्षक के साथ TypeScript सीखें — निःशुल्क

अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।

पाठ्यक्रम
20
पाठ
76

अक्सर पूछे जाने वाले प्रश्न

क्या “Socket Connections का प्रमाणीकरण और सुरक्षा” पाठ निःशुल्क है?

हाँ—“Socket Connections का प्रमाणीकरण और सुरक्षा” का पूरा पाठ यहाँ वेब पर निःशुल्क पढ़ा जा सकता है। इंटरैक्टिव अभ्यास (अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर) करने और NestJS एंटरप्राइज़ बैकएंड API पाठ्यक्रम का बाकी हिस्सा अनलॉक करने के लिए CoddyKit PRO लें। NestJS एंटरप्राइज़ बैकएंड API पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

“Socket Connections का प्रमाणीकरण और सुरक्षा” में मैं क्या सीखूँगा?

सुरक्षित realtime access के लिए handshake और message events पर guards तथा token verification लागू कीजिए। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ NestJS एंटरप्राइज़ बैकएंड API का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।

क्या NestJS एंटरप्राइज़ बैकएंड API शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?

पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर NestJS एंटरप्राइज़ बैकएंड API शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 2वाँ पाठ है।

“Socket Connections का प्रमाणीकरण और सुरक्षा” पाठ पूरा करने में कितना समय लगता है?

CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।

क्या मैं इस NestJS एंटरप्राइज़ बैकएंड API पाठ में कोड लिख और चला सकता हूँ?

हाँ। हर NestJS एंटरप्राइज़ बैकएंड API पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।

इस पाठ्यक्रम के सभी पाठ

  1. Socket.IO Adapter के साथ WebSocket Gateways
  2. Socket Connections का प्रमाणीकरण और सुरक्षा
  3. एकतरफ़ा Push के लिए Server-Sent Events
  4. Redis Pub/Sub Adapter से Realtime Scaling
← NestJS एंटरप्राइज़ बैकएंड API पर वापस जाएँ