Socket.IO তে Middleware হল একটি ফাংশন যা ইভেন্টের প্রসেসিং এর আগে বা পরে কার্যকর করা হয়। মিডলওয়্যার এর মাধ্যমে আপনি ক্লায়েন্টের অনুরোধ যাচাই করতে, ডেটা পরিবর্তন করতে বা লগিং, অথেনটিকেশন, অথবা অন্য কোনো প্রক্রিয়া সম্পাদন করতে পারেন। এর ফলে, সার্ভারকে আরও দক্ষ এবং সুরক্ষিত করা সম্ভব হয়।
Middleware কী?
মিডলওয়্যার হলো একটি ফাংশন বা প্রক্রিয়া যা ক্লায়েন্ট এবং সার্ভারের মধ্যে ইভেন্ট হ্যান্ডলিং এর আগে বা পরে কাজ করে। এটি ক্লায়েন্টের connection থেকে disconnect পর্যন্ত বিভিন্ন ধাপে কার্যকর হতে পারে।
Socket.IO-তে মিডলওয়্যার সাধারনত দুটি জায়গায় ব্যবহৃত হয়:
- Connection Middleware: ক্লায়েন্ট সার্ভারের সাথে কানেক্ট হওয়ার সময় আগে কাজ করে।
- Event Middleware: বিশেষ কোনো ইভেন্টের জন্য মিডলওয়্যার ব্যবহৃত হয়, যা ক্লায়েন্ট থেকে ইভেন্ট গ্রহণের আগে কার্যকর হয়।
Socket.IO তে Middleware ব্যবহার করা
1. Connection Middleware
ক্লায়েন্টের কানেকশন হতে হবে এবং তার আগে কিছু যাচাই বা অন্যান্য কাজ করতে হলে, connection middleware ব্যবহার করা হয়। এখানে আমরা একটি অথেনটিকেশন যাচাইয়ের উদাহরণ দেব।
Connection Middleware উদাহরণ
const http = require('http');
const socketIo = require('socket.io');
// HTTP সার্ভার তৈরি করা
const server = http.createServer((req, res) => {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Socket.IO server is running');
});
const io = socketIo(server);
// Connection Middleware (authenticating users)
io.use((socket, next) => {
const token = socket.handshake.query.token; // ক্লায়েন্ট থেকে টোকেন নেওয়া
if (token === 'valid-token') { // টোকেন যাচাই
console.log('User authenticated');
return next(); // ক্লায়েন্টকে কানেক্ট হতে দেওয়া
} else {
const err = new Error('Authentication error');
err.data = { message: 'Invalid token' }; // এরর মেসেজ
next(err); // কানেকশন বন্ধ করা
}
});
// Connection Event
io.on('connection', (socket) => {
console.log('A user connected');
socket.on('disconnect', () => {
console.log('User disconnected');
});
});
server.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});ব্যাখ্যা:
io.use(): এটি একটি মিডলওয়্যার ফাংশন যা connection এর আগে চলবে এবং next() কল করলে, কানেকশন সম্পূর্ণ হবে। যদি যাচাই ব্যর্থ হয়, তাহলে next(err) কল করে ক্লায়েন্টকে কানেক্ট হতে দেওয়া হবে না।socket.handshake.query.token: এটি ক্লায়েন্টের handshake এ পাঠানো তথ্য (যেমন টোকেন) থেকে তথ্য নেয়ার জন্য ব্যবহৃত হয়।
2. Event Middleware
এখন ধরুন, আপনি একটি ইভেন্ট (যেমন "send message") শোনার আগে কিছু যাচাই করতে চান। Event middleware ব্যবহার করে আপনি নির্দিষ্ট ইভেন্টের জন্য যাচাই বা ডেটা পরিবর্তন করতে পারেন।
Event Middleware উদাহরণ
const http = require('http');
const socketIo = require('socket.io');
// HTTP সার্ভার তৈরি করা
const server = http.createServer((req, res) => {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Socket.IO server is running');
});
const io = socketIo(server);
// Event Middleware (send message ইভেন্টের জন্য)
io.on('connection', (socket) => {
socket.on('send message', (message, callback) => {
if (message && message.length > 0) {
console.log('Message received:', message);
callback('Message received successfully');
} else {
callback('Error: Message cannot be empty');
}
});
});
server.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});ব্যাখ্যা:
socket.on('send message', (message, callback) => {...}): এখানে, ক্লায়েন্ট থেকে আসাsend messageইভেন্টের মধ্যে যাচাই করা হচ্ছে যে মেসেজটি ফাঁকা না কি না।callback(): এটি সার্ভার থেকে ক্লায়েন্টকে প্রতিক্রিয়া পাঠাতে ব্যবহৃত হয়। মিডলওয়্যার ফাংশনটি ক্লায়েন্টকে প্রতিক্রিয়া দেওয়ার আগে যাচাই করে, এবং যদি কিছু ভুল থাকে তবে তা ফেরত পাঠায়।
3. Error Handling in Middleware
Socket.IO তে মিডলওয়্যার ফাংশনে ত্রুটি হ্যান্ডলিং খুবই গুরুত্বপূর্ণ। যদি মিডলওয়্যার ফাংশনে কোনো ত্রুটি হয়, তাহলে আপনি সেই ত্রুটিকে হ্যান্ডল করে ক্লায়েন্টকে উপযুক্ত মেসেজ পাঠাতে পারেন।
Error Handling উদাহরণ
const http = require('http');
const socketIo = require('socket.io');
// HTTP সার্ভার তৈরি করা
const server = http.createServer((req, res) => {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Socket.IO server is running');
});
const io = socketIo(server);
// Connection Middleware with Error Handling
io.use((socket, next) => {
try {
const token = socket.handshake.query.token;
if (!token || token !== 'valid-token') {
throw new Error('Authentication error');
}
next(); // If token is valid, continue the connection
} catch (err) {
next(new Error('Authentication failed')); // Handle error
}
});
// Connection Event
io.on('connection', (socket) => {
console.log('A user connected');
socket.on('send message', (message) => {
if (!message || message.length === 0) {
socket.emit('error', 'Message cannot be empty');
} else {
console.log('Message received:', message);
socket.emit('receive message', 'Message received');
}
});
socket.on('disconnect', () => {
console.log('User disconnected');
});
});
server.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});ব্যাখ্যা:
- Error Handling in Middleware: এখানে মিডলওয়্যার ফাংশনে যদি কোনো ত্রুটি হয় (যেমন, ভুল টোকেন), তবে তা next() এর মাধ্যমে হ্যান্ডল করা হয় এবং ক্লায়েন্টে একটি ত্রুটি পাঠানো হয়।
socket.emit('error', 'Message cannot be empty'): ক্লায়েন্টে যদি মেসেজ না থাকে, তবে একটি ত্রুটি মেসেজ পাঠানো হয়।
4. ব্যবহার ক্ষেত্র
Socket.IO তে Middleware ব্যবহার করার জন্য কিছু সাধারণ ক্ষেত্রে:
- অথেনটিকেশন: ক্লায়েন্টের টোকেন যাচাই করতে মিডলওয়্যার ব্যবহার করা হয়।
- ডেটা ভ্যালিডেশন: ইভেন্টে প্রাপ্ত ডেটা যাচাই করা (যেমন, বার্তা ফাঁকা না হলে পাঠানো হবে)।
- থ্রটলিং: ইভেন্টে অনেক বেশি রিকোয়েস্ট আসলে তা সীমিত করার জন্য (যেমন, ক্লায়েন্টকে নির্দিষ্ট সময় পরপর একাধিক ইভেন্ট পাঠানোর অনুমতি দেয়া)।
- লগিং: ইভেন্টগুলির লগ রাখা, যাতে সিস্টেমের কার্যক্রম মনিটর করা যায়।
- এপিআই রেট লিমিটিং: যদি একটি ক্লায়েন্ট খুব বেশি ইভেন্ট পাঠায়, তাহলে সেটি রেট লিমিটিং করতে সাহায্য করে।
সারসংক্ষেপ
- Socket.IO তে Middleware একটি গুরুত্বপূর্ণ টুল যা connection এবং event-এর আগে বা পরে কার্যকর হয়। এটি ব্যবহারকারীর অথেনটিকেশন, ডেটা যাচাই, এবং ত্রুটি হ্যান্ডলিং করার জন্য ব্যবহৃত হয়।
- connection middleware দিয়ে আমরা ক্লায়েন্টের কানেকশন আগেই যাচাই করতে পারি, এবং event middleware দিয়ে নির্দিষ্ট ইভেন্টের আগে ডেটা যাচাই বা পরিবর্তন করতে পারি।
- Error handling মিডলওয়্যারের মাধ্যমে সঠিকভাবে পরিচালনা করা গেলে সিস্টেমের স্থিতিশীলতা এবং ব্যবহারকারীর অভিজ্ঞতা উন্নত হয়।
Socket.IO তে মিডলওয়্যার ব্যবহারের মাধ্যমে আপনি আপনার অ্যাপ্লিকেশনকে আরও সুরক্ষিত, কার্যকর এবং মডুলার করতে পারবেন।
Middleware হল একটি সফটওয়্যার প্যাটার্ন বা কনসেপ্ট যা অ্যাপ্লিকেশন আর্কিটেকচারে বিভিন্ন কম্পোনেন্টের মধ্যে একটি মধ্যবর্তী স্তর হিসেবে কাজ করে। এটি সাধারণত সার্ভারের রিকোয়েস্ট এবং রেসপন্সের প্রক্রিয়ার মাঝে কাজ করে এবং বিভিন্ন কাজ যেমন প্রমাণীকরণ, লগিং, ইনপুট ভ্যালিডেশন, এবং আরও অনেক কাজ সম্পাদন করে।
Middleware হল একটি ফাংশন বা প্রোগ্রাম যা ক্লায়েন্ট এবং সার্ভারের মধ্যে অবস্থান নেয় এবং সিস্টেমের সেন্ট্রাল লজিক বা প্রক্রিয়ায় প্রভাব ফেলে। এটি অ্যাপ্লিকেশনকে আরও সংগঠিত, মডুলার, এবং পুনঃব্যবহারযোগ্য করে তোলে।
Middleware এর প্রয়োজনীয়তা
- কম্পোনেন্ট আলাদা করা (Separation of Concerns):
- Middleware ব্যবহারের মাধ্যমে আপনি বিভিন্ন কার্যক্রম (যেমন প্রমাণীকরণ, লগিং, নিরাপত্তা চেক) আলাদা করতে পারেন এবং অ্যাপ্লিকেশনের মূল লজিক থেকে এগুলো বিচ্ছিন্ন রাখতে পারেন। এর ফলে কোড ক্লিন এবং রক্ষণাবেক্ষণ সহজ হয়।
- উদাহরণ: আপনি লগিং এবং প্রমাণীকরণের কাজ Middleware-এ রাখতে পারেন, ফলে অ্যাপ্লিকেশনের মূল লজিক শুধু ব্যবসায়িক কার্যক্রম সম্পাদন করতে মনোনিবেশ করবে।
- এফিশিয়েন্ট রিকোয়েস্ট প্রসেসিং:
- Middleware ব্যবহারের মাধ্যমে আপনি অ্যাপ্লিকেশনের বিভিন্ন স্তরের কাজ সুনির্দিষ্টভাবে প্রক্রিয়া করতে পারেন। এটি রিকোয়েস্ট এবং রেসপন্সের মধ্যে একটি ফিল্টার হিসেবে কাজ করে, যা ডেটার প্রক্রিয়াকরণ আরও দ্রুত এবং কার্যকরী করে।
- উদাহরণ: ইনপুট ভ্যালিডেশন, এক্সেস কন্ট্রোল ইত্যাদি রিকোয়েস্ট প্রসেসিংয়ের প্রথম স্তরে Middleware দ্বারা করা যায়।
- পুনঃব্যবহারযোগ্য কোড:
- Middleware কোড বিভিন্ন অ্যাপ্লিকেশন বা প্রোজেক্টে পুনঃব্যবহারযোগ্য হতে পারে। একবার Middleware তৈরি করলে, আপনি এটি একাধিক রিকোয়েস্ট বা সার্ভিসে ব্যবহার করতে পারবেন। এটি ডুপ্লিকেট কোড লেখা কমিয়ে দেয়।
- উদাহরণ: প্রমাণীকরণ বা লগিং ফাংশন একবার Middleware হিসেবে তৈরি করলে, আপনি সেটি বিভিন্ন রাউট বা ফিচারে ব্যবহার করতে পারেন।
- সাব-সিস্টেম ইন্টিগ্রেশন:
- Middleware একটি অ্যাপ্লিকেশন এবং অন্যান্য সিস্টেমের মধ্যে সংযোগ স্থাপন করতে ব্যবহৃত হয়। এটি বিভিন্ন সেবা এবং পদ্ধতির মধ্যে যোগাযোগ স্থাপন করতে সাহায্য করে। উদাহরণস্বরূপ, API গেটওয়ে হিসেবে কাজ করা, যেখানে একাধিক সার্ভিসের মধ্যে ডেটা আদান-প্রদান করা হয়।
- নিরাপত্তা:
- Middleware নিরাপত্তা ব্যবস্থার জন্য অত্যন্ত গুরুত্বপূর্ণ। এটি প্রমাণীকরণ (authentication), অথরাইজেশন (authorization), এবং অন্যান্য নিরাপত্তা চেক সম্পাদন করতে সহায়তা করে।
- উদাহরণ: একটি অ্যাপ্লিকেশনের Middleware তে প্রমাণীকরণ এবং অথরাইজেশন ফাংশন তৈরি করা যেতে পারে, যা নির্ধারণ করবে যে কোন ব্যবহারকারী কোন রিসোর্স অ্যাক্সেস করতে পারবে।
- ডিবাগিং এবং লগিং:
- Middleware ডিবাগিং এবং লগিং সিস্টেমের জন্য গুরুত্বপূর্ণ। এটি আপনার অ্যাপ্লিকেশনের কার্যক্রম পর্যবেক্ষণ করতে সাহায্য করে এবং যে কোনো সমস্যা বা ত্রুটি সনাক্ত করতে সহায়তা করে।
- উদাহরণ: প্রতিটি HTTP রিকোয়েস্টের আগে এবং পরে লগ রাখা, অথবা প্রতিটি অ্যাক্সেসের ক্ষেত্রে ফাইল তৈরি করা।
- ট্রান্সফর্মেশন এবং ফিল্টারিং:
- Middleware ডেটার ট্রান্সফর্মেশন বা ফিল্টারিং করার জন্য ব্যবহৃত হতে পারে। এটি রিকোয়েস্ট এবং রেসপন্সে ডেটা সংশোধন করতে সক্ষম, যেমন: JSON ডেটা প্রসেসিং বা কাস্টম হেডার সেটিং।
- উদাহরণ: একটি API যেখানে রিকোয়েস্টে প্রাপ্ত ডেটাকে ফিল্টার করে বা পরিবর্তন করে সার্ভারের কাছে পাঠানো হয়।
Middleware এর উদাহরণ
Node.js (Express) Middleware Example:
Express.js একটি জনপ্রিয় Node.js ফ্রেমওয়ার্ক, যেখানে Middleware ব্যবহারের মাধ্যমে আপনি রিকোয়েস্টের প্রক্রিয়া কাস্টমাইজ করতে পারেন।
const express = require('express');
const app = express();
// Simple logging middleware
app.use((req, res, next) => {
console.log(`${req.method} request to ${req.url}`);
next(); // Pass control to the next middleware
});
// Authentication middleware
app.use('/protected', (req, res, next) => {
const token = req.headers['authorization'];
if (token === 'valid-token') {
next();
} else {
res.status(401).send('Unauthorized');
}
});
// Route for public access
app.get('/', (req, res) => {
res.send('Public Route');
});
// Route for protected access
app.get('/protected', (req, res) => {
res.send('Protected Route');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});Explanation:
- প্রথম middleware লগিং-এর কাজ করে, যেখানে প্রতিটি রিকোয়েস্টের HTTP মেথড এবং URL কনসোল লগ করা হয়।
- দ্বিতীয় middleware
/protectedরুটে প্রমাণীকরণ (authentication) চেক করে, এবং যদি টোকেন সঠিক না হয়, তাহলে 401 Unauthorized রেসপন্স ফেরত দেয়।
Middleware এর ধরন
- রিকোয়েস্ট প্রসেসিং Middleware:
- যেমন প্রমাণীকরণ (authentication), ইনপুট ভ্যালিডেশন, ডেটা ফিল্টারিং ইত্যাদি।
- লগিং এবং ডিবাগিং Middleware:
- সার্ভারের কার্যকলাপ লগ করা বা ডিবাগিং ইনফরমেশন সংগ্রহ করা।
- রেসপন্স প্রসেসিং Middleware:
- রেসপন্সের ডেটা পরিবর্তন বা কাস্টম রেসপন্স তৈরি করা।
- সেশন বা কুকি Middleware:
- সেশন ম্যানেজমেন্ট বা কুকি হ্যান্ডলিং করা।
- এপিআই কিউ ম্যানেজমেন্ট:
- API requests এর জন্য রেট লিমিটিং বা queue management।
সারসংক্ষেপ
Middleware হল একটি সফটওয়্যার ফাংশন যা অ্যাপ্লিকেশনের রিকোয়েস্ট এবং রেসপন্স প্রক্রিয়ার মধ্যে কার্যকরী ভূমিকা পালন করে। এটি প্রমাণীকরণ, লগিং, ইনপুট ভ্যালিডেশন, রিসোর্স শেয়ারিং, ডেটা প্রসেসিং, সেশন ম্যানেজমেন্ট ইত্যাদি কাজ সহজভাবে করতে সহায়তা করে। Middleware ব্যবহার করলে অ্যাপ্লিকেশনের কোড সহজ, পরিষ্কার, এবং মডুলার হয়, এবং এটি অ্যাপ্লিকেশনকে আরও নিরাপদ ও স্কেলেবল করে তোলে।
Socket.IO তে middleware ব্যবহার করে আপনি কানেকশন পরিচালনা, ডেটা যাচাই, অথেনটিকেশন, লগিং, বা অন্যান্য কাস্টম লজিক ইনজেক্ট করতে পারেন। Socket.IO তে middleware এমন ফাংশন যা ইভেন্ট হ্যান্ডলিং এর আগে রান হয় এবং সার্ভারের সাথে ক্লায়েন্টের সংযোগ স্থাপনের সময় কাস্টম যাচাই বা প্রক্রিয়া সম্পাদন করতে সহায়তা করে।
এখানে, আমরা একটি custom middleware তৈরি করব এবং সেটি Socket.IO তে কিভাবে ব্যবহার করা যায় তা দেখব।
1. Socket.IO Middleware কী?
Socket.IO তে middleware হল এমন ফাংশন যা সার্ভারের সাথে ক্লায়েন্টের কানেকশন স্থাপন বা ইভেন্ট প্রসেসিং এর আগে রান হয়। এটি সাধারণত ক্লায়েন্ট থেকে আসা ডেটা যাচাই করতে বা অন্য কোনো প্রক্রিয়া করতে ব্যবহৃত হয়।
Socket.IO তে middleware মূলত io.use() এবং socket.use() এর মাধ্যমে ব্যবহৃত হয়।
io.use(): এটি সার্ভার-সর্বজনীন middleware হিসেবে কাজ করে এবং সবsocketএর জন্য প্রযোজ্য হয়।socket.use(): এটি শুধুমাত্র নির্দিষ্ট socket এর জন্য middleware হিসাবে ব্যবহৃত হয়।
2. Socket.IO Middleware তৈরি এবং ব্যবহার
2.1 Custom Middleware তৈরি করা
এখানে আমরা একটি কাস্টম middleware তৈরি করব যা authentication যাচাই করবে। ক্লায়েন্ট একটি JWT token পাঠাবে এবং সার্ভার সেটি যাচাই করে নিশ্চিত করবে যে ক্লায়েন্ট অনুমোদিত কি না।
2.2 Middleware কোড উদাহরণ (Node.js)
const http = require('http');
const socketIo = require('socket.io');
const jwt = require('jsonwebtoken');
// HTTP সার্ভার তৈরি
const server = http.createServer((req, res) => {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Socket.IO Server');
});
// Socket.IO সার্ভার তৈরি
const io = socketIo(server);
// Secret key (JWT token এর জন্য)
const SECRET_KEY = 'your_secret_key';
// Custom Middleware function: JWT validation
function authenticate(socket, next) {
const token = socket.handshake.query.token; // JWT token query থেকে নিতে হবে
if (!token) {
return next(new Error('Authentication error: No token provided')); // Token না থাকলে Error
}
// JWT token যাচাই করা
jwt.verify(token, SECRET_KEY, (err, decoded) => {
if (err) {
return next(new Error('Authentication error: Invalid token')); // Invalid token থাকলে Error
}
socket.user = decoded; // Token সঠিক হলে decoded তথ্য socket এর সাথে যুক্ত করা
next(); // middleware সফল হলে connection অনুমোদিত
});
}
// Middleware সার্ভারে ব্যবহার করা (Global level)
io.use(authenticate);
// ক্লায়েন্ট কানেক্ট হলে
io.on('connection', (socket) => {
console.log('A user connected with ID:', socket.id);
console.log('Authenticated User:', socket.user); // Authentication success হলে decoded user data
socket.on('disconnect', () => {
console.log('User disconnected');
});
});
// সার্ভার 3000 পোর্টে চলবে
server.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});এখানে, আমরা authenticate নামে একটি কাস্টম middleware তৈরি করেছি যা JWT token যাচাই করে। যদি token না থাকে বা তা অকার্যকর হয়, তবে ক্লায়েন্টের কানেকশন ব্যর্থ হয়ে যাবে। যদি token সঠিক হয়, তবে ক্লায়েন্টের তথ্য socket.user এ সংরক্ষিত হবে এবং next() কল হবে, যার মাধ্যমে কানেকশন অনুমোদিত হবে।
2.3 ক্লায়েন্ট সাইড (HTML + JavaScript)
ক্লায়েন্ট সাইডে, আমরা Socket.IO client ব্যবহার করে একটি JWT token পাঠাব এবং সার্ভার থেকে রেসপন্স গ্রহণ করব।
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Socket.IO JWT Authentication</title>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<h1>Socket.IO JWT Authentication</h1>
<div id="messages"></div>
<script>
// JWT Token (এটি সাধারণত সার্ভার থেকে ক্লায়েন্টকে পাঠানো হয়)
const token = 'your_jwt_token_here'; // বাস্তব জীবনে এটি লগইন প্রক্রিয়া শেষে পাওয়া যাবে
// সার্ভারের সাথে সংযোগ স্থাপন (Token পাঠানো)
var socket = io('http://localhost:3000', {
query: { token: token } // Token এখানে query প্যারামিটার হিসেবে পাঠানো হচ্ছে
});
// সার্ভার থেকে রেসপন্স গ্রহণ
socket.on('connect', function() {
console.log('Connected to the server');
});
socket.on('disconnect', function() {
console.log('Disconnected from the server');
});
</script>
</body>
</html>এখানে, ক্লায়েন্ট token পাঠাচ্ছে সার্ভারে, এবং সার্ভার এই token যাচাই করে নিশ্চিত করে যে ক্লায়েন্ট অনুমোদিত। যদি token সঠিক হয়, তাহলে সার্ভার ক্লায়েন্টকে কানেকশন অনুমোদন করবে।
3. Socket.IO Middleware এর অন্যান্য ব্যবহার
3.1 Log Events (Logging Middleware)
function logConnection(socket, next) {
console.log('A new connection established');
next(); // Connection অনুমোদন
}
io.use(logConnection); // Middleware হিসাবে ব্যবহারএই middleware ক্লায়েন্ট কানেক্ট হওয়ার পর একটি লগ ইনপুট করবে, যা ট্রাবলশুটিং বা ম্যানেজমেন্টে সহায়তা করতে পারে।
3.2 Rate Limiting (Prevent Spam)
const rateLimit = {};
function rateLimiter(socket, next) {
const userId = socket.id;
const currentTime = Date.now();
if (rateLimit[userId] && currentTime - rateLimit[userId] < 1000) {
return next(new Error('Too many requests! Please try again later.'));
}
rateLimit[userId] = currentTime;
next();
}
io.use(rateLimiter); // Middleware হিসাবে ব্যবহারএই middleware এক মিনিটের মধ্যে একটি ক্লায়েন্টের বেশি রিকোয়েস্ট ব্লক করবে, যা স্প্যাম বা অস্বাভাবিক ব্যবহারকে প্রতিরোধ করতে সাহায্য করবে।
সারসংক্ষেপ
- Socket.IO Middleware হল এমন ফাংশন যা ক্লায়েন্টের সংযোগের পূর্বে চলতে পারে এবং এটি বিভিন্ন কাস্টম লজিক যেমন অথেনটিকেশন, লগিং, রেট লিমিটিং ইত্যাদি বাস্তবায়ন করতে ব্যবহৃত হয়।
io.use()এবংsocket.use()এর মাধ্যমে middleware ব্যবহার করা হয়।- Custom Middleware তৈরি করে আপনি Socket.IO তে বিভিন্ন নিরাপত্তা বা কার্যকরী ব্যবস্থা অন্তর্ভুক্ত করতে পারেন।
এইভাবে Socket.IO তে custom middleware তৈরি করে আপনি রিয়েল-টাইম অ্যাপ্লিকেশনগুলির মধ্যে আরো নিরাপদ এবং কার্যকরী প্রক্রিয়া প্রয়োগ করতে পারেন।
Middleware একটি অত্যন্ত শক্তিশালী কৌশল যা ব্যবহৃত হয় অ্যাপ্লিকেশনগুলিতে ডেটা ভ্যালিডেশন এবং সিকিউরিটি ম্যানেজমেন্টের জন্য। Middleware হল ফাংশনগুলির একটি চেইন যা ক্লায়েন্টের রিকোয়েস্ট সার্ভারে পৌঁছানোর আগে এবং সার্ভার থেকে রেসপন্স পাঠানোর আগে চালিত হয়। এটি অনেক ধরনের কাজ যেমন Data Validation, Authentication, Authorization, Rate Limiting, Logging, এবং Security Measures করতে পারে।
Socket.IO বা Express.js এর মতো Node.js ফ্রেমওয়ার্কে middleware এর মাধ্যমে আপনি সহজেই data validation এবং security ব্যবস্থা নিশ্চিত করতে পারেন।
Data Validation Middleware
Data Validation একটি প্রক্রিয়া যার মাধ্যমে নিশ্চিত করা হয় যে ইনপুট ডেটা সঠিক, পূর্ণ এবং প্রত্যাশিত ফরম্যাটে রয়েছে। Node.js এ middleware ব্যবহার করে ডেটা ভ্যালিডেশন খুব সহজেই করা যেতে পারে।
Data Validation Example (Express.js)
এখানে আমরা একটি কাস্টম middleware ব্যবহার করব যা ইনপুট ডেটার validation করবে, যেমন ফর্মে নাম এবং ইমেইল ফিল্ডের সঠিকতা যাচাই করা।
const express = require('express');
const app = express();
app.use(express.json()); // JSON বডি পার্সিং
// Data validation middleware
function validateUserData(req, res, next) {
const { name, email } = req.body;
// নাম এবং ইমেইল চেক করা
if (!name || !email) {
return res.status(400).json({ message: 'Name and email are required' });
}
// ইমেইল ফরম্যাট চেক করা
const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;
if (!emailRegex.test(email)) {
return res.status(400).json({ message: 'Invalid email format' });
}
// সব কিছু ঠিক থাকলে, পরবর্তী middleware বা রুট হ্যান্ডলার কল করা হবে
next();
}
// রাউট যেখানে ভ্যালিডেশন প্রয়োগ করা হবে
app.post('/user', validateUserData, (req, res) => {
res.status(200).json({ message: 'User data is valid' });
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});ব্যাখ্যা:
- validateUserData ফাংশনটি একটি middleware যা
/userরাউটে POST রিকোয়েস্ট পাঠানোর আগে ইনপুট ডেটার যাচাই করে। এটি নিশ্চিত করে যে name এবং email ঠিকমত পূর্ণ এবং সঠিক ফরম্যাটে আছে। - Email regex ব্যবহার করে ইমেইল ঠিক ফরম্যাটে কিনা তা যাচাই করা হয়। যদি কোনো সমস্যা থাকে, তবে ৪০০ (Bad Request) স্ট্যাটাস কোড সহ একটি ত্রুটি বার্তা পাঠানো হয়।
Security Middleware
Security Middleware নিরাপত্তা নিশ্চিত করতে ব্যবহৃত হয় এবং এটি একাধিক ধরনের কাজ করতে পারে, যেমন Authentication, Authorization, Cross-Site Request Forgery (CSRF) প্রটেকশন, Rate Limiting, CORS, Input Sanitization, ইত্যাদি। এগুলোর মাধ্যমে সিস্টেমকে বিভিন্ন ধরনের আক্রমণ থেকে সুরক্ষিত রাখা যায়।
Security Middleware Example (Express.js)
এখানে কিছু সিকিউরিটি ভ্যালিডেশন প্রক্রিয়া দেখানো হয়েছে:
- Authentication Middleware: লগইন সেশন বা টোকেন যাচাই করা।
- CORS Middleware: ক্রস-অরিজিন রিকোয়েস্ট নিয়ন্ত্রণ করা।
- Rate Limiting Middleware: একই IP থেকে অতিরিক্ত রিকোয়েস্ট রোধ করা।
const express = require('express');
const cors = require('cors');
const rateLimit = require('express-rate-limit');
const app = express();
// CORS Middleware: ক্রস-অরিজিন রিকোয়েস্ট নিয়ন্ত্রণ
app.use(cors());
// Rate Limiting Middleware: একে একে প্রতি IP থেকে রিকোয়েস্ট সংখ্যা সীমিত করা
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 মিনিট
max: 100, // প্রতি ১৫ মিনিটে ১০০ রিকোয়েস্ট অনুমোদিত
message: 'Too many requests from this IP, please try again later'
});
app.use(limiter);
// Authentication Middleware
function authenticate(req, res, next) {
const token = req.headers['authorization'];
if (!token) {
return res.status(401).json({ message: 'No token provided' });
}
// সিম্পল টোকেন চেক (প্রোডাকশনে JWT ব্যবহার করা উচিত)
if (token !== 'valid_token') {
return res.status(403).json({ message: 'Invalid token' });
}
next();
}
// একটি সুরক্ষিত রাউট যা অথেনটিকেশন চেক করে
app.get('/secure-data', authenticate, (req, res) => {
res.status(200).json({ message: 'Secure data accessed' });
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});ব্যাখ্যা:
- CORS Middleware: এটি সব ধরনের ক্রস-অরিজিন রিকোয়েস্টের জন্য অনুমতি দেয়।
- Rate Limiting:
express-rate-limitপ্যাকেজটি ব্যবহার করে একে একে প্রতি IP থেকে রিকোয়েস্ট সংখ্যা সীমিত করা হয়েছে। এটি আপনার অ্যাপ্লিকেশনকে DDoS আক্রমণ থেকে সুরক্ষিত রাখতে সাহায্য করে। - Authentication Middleware: এটি প্রতি রিকোয়েস্টে Authorization token যাচাই করে। যদি টোকেন সঠিক না হয়, তবে 401 Unauthorized অথবা 403 Forbidden ত্রুটি পাঠানো হয়।
Data Validation ও Security এর Middleware ব্যাবহার করার সুবিধা
- Centralized Validation: Validation এবং security কেবল একটি জায়গায় করা হয়, যা কোডের পুনঃব্যবহারযোগ্যতা এবং রক্ষণাবেক্ষণ সহজ করে।
- Code Separation: Middleware ব্যবহারে ভ্যালিডেশন এবং নিরাপত্তা সংক্রান্ত কোড মূল লজিক থেকে আলাদা থাকে, ফলে অ্যাপ্লিকেশন কোড পরিষ্কার এবং মডুলার হয়।
- Preemptive Security: মিসিং বা ভুল ডেটা বা সিকিউরিটি থ্রেটগুলি রিকোয়েস্ট হ্যান্ডলার পর্যন্ত পৌঁছানোর আগেই ব্লক করা যায়।
সারসংক্ষেপ
- Data Validation Middleware: এটি ইনপুট ডেটার সঠিকতা নিশ্চিত করে, যেমন নাম এবং ইমেইল যাচাই করা।
- Security Middleware: এটি অ্যাপ্লিকেশনকে সুরক্ষিত রাখে এবং ব্যবহারকারীদের অথেনটিকেশন, অথরাইজেশন এবং রেট লিমিটিং সহ নিরাপত্তা প্রদান করে।
- Express.js বা অন্য কোনো Node.js ফ্রেমওয়ার্কে middleware ব্যবহার করে আপনি সহজে data validation এবং security এর ব্যবস্থা নিশ্চিত করতে পারেন, যা সিস্টেমের স্থিতিশীলতা এবং নিরাপত্তা নিশ্চিত করে।
Middleware হল একটি ফাংশন যা সার্ভারের রিকোয়েস্ট-রেসপন্স চেইনের মধ্যে অবস্থিত, এবং এটি বিভিন্ন কাজ যেমন রিকোয়েস্ট প্রক্রিয়াকরণ, অথেনটিকেশন, ভ্যালিডেশন, বা লোগিং করতে ব্যবহৃত হয়। বিশেষ করে Express.js (Node.js এর ওয়েব ফ্রেমওয়ার্ক) এ Middleware খুবই জনপ্রিয়, এবং এখানে একাধিক ধরনের middleware তৈরি এবং প্রয়োগ করা সম্ভব।
এই টিউটোরিয়ালে আমরা middleware কীভাবে কাজ করে এবং কীভাবে এটি request-handling pipeline-এ প্রয়োগ করা যায় তা একটি উদাহরণের মাধ্যমে দেখবো।
Express.js Middleware Implementation Example
Step 1: Express.js Setup
প্রথমে, Express.js ইনস্টল করা প্রয়োজন। নিচে কমান্ডটি ব্যবহার করে Express.js ইনস্টল করুন:
npm init -y
npm install expressStep 2: Basic Express Server
Express.js এর একটি বেসিক সার্ভার তৈরি করা যাক।
const express = require('express');
const app = express();
const port = 3000;
// বেসিক রুট
app.get('/', (req, res) => {
res.send('Hello, Express Middleware!');
});
// সার্ভার চালু
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});Step 3: Middleware Implementation
Express.js-এ middleware প্রাথমিকভাবে দুইভাবে কাজ করে:
- Global Middleware: এটি সার্ভারের সমস্ত রিকোয়েস্টে কাজ করবে।
- Route-specific Middleware: এটি শুধু নির্দিষ্ট রুটের রিকোয়েস্টের জন্য কাজ করবে।
1. Global Middleware (All Routes)
Global middleware হল এমন একটি middleware যা সমস্ত রিকোয়েস্টের জন্য কাজ করে। আমরা এখানে একটি লগিং middleware তৈরি করবো যা প্রতিটি রিকোয়েস্টের তথ্য কনসোলে প্রিন্ট করবে।
// Logging Middleware
app.use((req, res, next) => {
console.log(`${req.method} request made to: ${req.url}`);
next(); // Next middleware বা রুট হ্যান্ডলারের কাছে পাস করা
});এটি app.use() এর মাধ্যমে সার্ভারের সব রিকোয়েস্টের জন্য এক্সিকিউট হবে এবং প্রতিটি রিকোয়েস্টের method (GET, POST ইত্যাদি) এবং url কনসোলে প্রিন্ট করবে।
2. Route-Specific Middleware
এটি শুধুমাত্র নির্দিষ্ট রুটের জন্য কার্যকর হবে। নিচে একটি middleware উদাহরণ দেখানো হচ্ছে যা শুধু /admin রুটে কাজ করবে।
// Admin Route Middleware
const checkAdmin = (req, res, next) => {
const isAdmin = req.query.admin === 'true'; // URL এ query parameter চেক করা
if (isAdmin) {
next(); // যদি ইউজার admin হয়, পরবর্তী রাউটে যাবে
} else {
res.status(403).send('Access denied! You are not an admin.');
}
};
// /admin রুটে middleware প্রয়োগ করা
app.get('/admin', checkAdmin, (req, res) => {
res.send('Welcome Admin!');
});এখানে, /admin রুটে গেলে প্রথমে checkAdmin middleware চলবে। যদি ইউজার admin=true প্যারামিটার পাঠায়, তাহলে next() কল হবে এবং পরবর্তী রাউট হ্যান্ডলার (যেখানে "Welcome Admin!" পাঠানো হবে) এক্সিকিউট হবে। যদি ইউজার admin না হয়, তবে 403 Access Denied মেসেজ দেখানো হবে।
Step 4: Combining All Together
এখন সমস্ত middleware এবং রাউটগুলো একত্রে ব্যবহার করি:
const express = require('express');
const app = express();
const port = 3000;
// Logging Middleware (Global Middleware)
app.use((req, res, next) => {
console.log(`${req.method} request made to: ${req.url}`);
next();
});
// Admin Route Middleware (Route-Specific Middleware)
const checkAdmin = (req, res, next) => {
const isAdmin = req.query.admin === 'true';
if (isAdmin) {
next();
} else {
res.status(403).send('Access denied! You are not an admin.');
}
};
// Basic Route
app.get('/', (req, res) => {
res.send('Hello, Express Middleware!');
});
// Admin Route with Middleware
app.get('/admin', checkAdmin, (req, res) => {
res.send('Welcome Admin!');
});
// Starting the Server
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});How It Works:
- Logging Middleware:
- এই middleware সব রিকোয়েস্টে কাজ করবে এবং প্রতিটি রিকোয়েস্টের
methodএবংurlকনসোলে দেখাবে।
- এই middleware সব রিকোয়েস্টে কাজ করবে এবং প্রতিটি রিকোয়েস্টের
- Admin Route Middleware:
/adminরুটে যাবার আগে checkAdmin middleware চেক করবে যে ইউজারadmin=trueপ্যারামিটার পাঠিয়েছে কি না। যদি পাঠায়, তবে অ্যাক্সেস দেবে, নতুবা 403 Access Denied দেখাবে।
Step 5: Testing
- Test Logging Middleware:
অ্যাপ্লিকেশনটি চালু করুন এবং
/রুটে গিয়ে দেখুন কনসোলে:GET request made to: /
- Test Admin Route:
/admin?admin=trueURL ব্যবহার করলে:GET request made to: /admin?admin=trueএবং আপনি পাবেন:
Welcome Admin!/admin?admin=falseবা/adminURL ব্যবহার করলে:Access denied! You are not an admin.
Error Handling Middleware
Error handling এর জন্য একটি কাস্টম middleware ব্যবহার করা হয়। এটি সাধারণত সব শেষে থাকে এবং ত্রুটিগুলি হ্যান্ডেল করে।
// Error handling Middleware
app.use((err, req, res, next) => {
console.error(err.stack); // Tstack trace print
res.status(500).send('Something went wrong!');
});এটি ব্যবহারকারীকে 500 Internal Server Error বার্তা পাঠাবে এবং সার্ভারে ঘটে যাওয়া ত্রুটির স্ট্যাক ট্রেস কনসোলে প্রিন্ট করবে।
সারসংক্ষেপ
- Middleware একাধিক ফাংশনের মাধ্যমে আপনার রিকোয়েস্ট হ্যান্ডলিং প্রক্রিয়া নিয়ন্ত্রণ করে এবং সার্ভার সাইডে ডেটা ভ্যালিডেশন, অথেনটিকেশন, লোগিং ইত্যাদি কার্য সম্পাদন করে।
- Express.js তে global middleware এবং route-specific middleware ব্যবহার করে আপনি নির্দিষ্ট রিকোয়েস্ট প্রক্রিয়াকরণ বা ত্রুটি হ্যান্ডলিং করতে পারেন।
- কাস্টম error handling middleware আপনার অ্যাপ্লিকেশনকে আরও স্থিতিশীল এবং user-friendly করে তোলে।
Middleware ব্যবহার করে আপনি আপনার অ্যাপ্লিকেশনের বিভিন্ন কার্যক্রম সহজে এবং কার্যকরভাবে পরিচালনা করতে পারেন।
Read more