JWT (JSON Web Token) Authentication

এক্সপ্রেসজেএস (ExpressJS) - Web Development

319

JWT (JSON Web Token) হল একটি ওপেন স্ট্যান্ডার্ড (RFC 7519) যা ব্যবহারকারীদের পরিচয় যাচাই করতে এবং তাদের জন্য নিরাপদভাবে তথ্য আদান প্রদান করতে ব্যবহৃত হয়। ExpressJS অ্যাপ্লিকেশনে JWT ব্যবহার করে আপনি একটি সুরক্ষিত অথেন্টিকেশন সিস্টেম তৈরি করতে পারেন। JWT-এর মূল উদ্দেশ্য হল, সার্ভার এবং ক্লায়েন্টের মধ্যে অথেন্টিকেশন তথ্য নিরাপদভাবে ভাগ করা, বিশেষ করে API ভিত্তিক অ্যাপ্লিকেশনগুলোর জন্য।

JWT সাধারণত দুটি গুরুত্বপূর্ণ অংশে বিভক্ত থাকে:

  1. Header: এটি এক্সপিরেশন টাইম, অ্যালগোরিদম (যেমন HMAC SHA256, RSA) ইত্যাদি ধারণ করে।
  2. Payload: এটি সাধারণত ব্যবহারকারী বা ক্লায়েন্ট সম্পর্কিত তথ্য ধারণ করে, যেমন ইউজারের আইডি, রোল, অথবা অন্যান্য প্রাসঙ্গিক ডেটা।
  3. Signature: এটি একটি সিকিউরিটি সিগনেচার যা এই টোকেনটি বৈধ কিনা তা যাচাই করতে ব্যবহৃত হয়।

১. JWT কীভাবে কাজ করে?

JWT সাধারণত authentication প্রক্রিয়ায় ব্যবহৃত হয়। এখানে সাধারণত তিনটি ধাপ থাকে:

  1. Login: ব্যবহারকারী তার ক্রিডেনশিয়াল দিয়ে লগইন করলে, সার্ভার একটি JWT তৈরি করে এবং তা ক্লায়েন্টকে ফেরত পাঠায়।
  2. Token Storage: ক্লায়েন্ট টোকেনটি তার সেশনে বা লোকালস্টোরেজে সংরক্ষণ করে রাখে।
  3. Request with Token: পরবর্তীতে, ক্লায়েন্ট সার্ভারে যেকোনো রিকোয়েস্ট পাঠালে JWT হেডারে সংযুক্ত করে পাঠায়। সার্ভার এই টোকেন যাচাই করে ব্যবহারকারীকে অথেন্টিকেট করে।

২. ExpressJS-এ JWT Authentication সেটআপ

এখানে, JWT অথেন্টিকেশন সেটআপ করার জন্য কয়েকটি স্টেপ রয়েছে:

২.১. প্রয়োজনীয় প্যাকেজগুলো ইনস্টল করা

প্রথমে, ExpressJS অ্যাপ্লিকেশন তৈরি করতে হবে এবং কিছু প্যাকেজ ইনস্টল করতে হবে:

npm install express jsonwebtoken bcryptjs dotenv
  • jsonwebtoken: JWT টোকেন তৈরি এবং যাচাই করার জন্য।
  • bcryptjs: পাসওয়ার্ড হ্যাশিং এবং নিরাপদ রাখতে।
  • dotenv: পরিবেশগত পরিবর্তনশীল (environment variables) ব্যবহার করতে।

২.২. ExpressJS অ্যাপ্লিকেশন তৈরি করা

const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const dotenv = require('dotenv');
const app = express();

// dotenv কনফিগার করা
dotenv.config();

// JSON বডি প্যার্স করা
app.use(express.json());

const users = [];  // ডাটাবেসের পরিবর্তে একটি সাম্পল অ্যারে

// JWT সিক্রেট কির জন্য .env ফাইল ব্যবহার করুন
const JWT_SECRET = process.env.JWT_SECRET;

// রেজিস্ট্রেশন রাউট
app.post('/register', async (req, res) => {
  const { username, password } = req.body;

  // পাসওয়ার্ড হ্যাশ করা
  const hashedPassword = await bcrypt.hash(password, 10);

  const newUser = {
    username,
    password: hashedPassword
  };

  users.push(newUser);  // ডাটাবেসে ব্যবহারকারী সংরক্ষণ
  res.status(201).json({ message: 'User registered successfully' });
});

// লগইন রাউট
app.post('/login', async (req, res) => {
  const { username, password } = req.body;

  // ব্যবহারকারী খুঁজে পাওয়া
  const user = users.find(user => user.username === username);
  
  if (!user) {
    return res.status(400).json({ message: 'User not found' });
  }

  // পাসওয়ার্ড যাচাই
  const isMatch = await bcrypt.compare(password, user.password);
  
  if (!isMatch) {
    return res.status(400).json({ message: 'Invalid credentials' });
  }

  // JWT তৈরি করা
  const token = jwt.sign({ username: user.username }, JWT_SECRET, { expiresIn: '1h' });

  // টোকেন ফেরত পাঠানো
  res.json({ token });
});

// একটি প্রটেক্টেড রাউট
app.get('/protected', (req, res) => {
  const token = req.headers['authorization'];

  if (!token) {
    return res.status(403).json({ message: 'No token provided' });
  }

  // টোকেন যাচাই
  jwt.verify(token, JWT_SECRET, (err, decoded) => {
    if (err) {
      return res.status(401).json({ message: 'Unauthorized' });
    }

    res.json({ message: 'Protected data', user: decoded.username });
  });
});

// সার্ভার চালু করা
const port = 5000;
app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});

ব্যাখ্যা:

  • Register রাউট: ব্যবহারকারীকে রেজিস্টার করার জন্য একটি POST রিকোয়েস্ট। পাসওয়ার্ডটি bcrypt ব্যবহার করে হ্যাশ করা হয় এবং এটি ডাটাবেসে (এখানে একটি অ্যারে) সংরক্ষিত হয়।
  • Login রাউট: ব্যবহারকারী তার ক্রিডেনশিয়াল দিয়ে লগইন করলে, সার্ভার পাসওয়ার্ড যাচাই করে JWT টোকেন তৈরি করে। এই টোকেনটি ক্লায়েন্টকে ফেরত পাঠানো হয়, যেটি পরবর্তীতে সমস্ত প্রটেক্টেড রিকোয়েস্টে ব্যবহার করা হবে।
  • Protected রাউট: ক্লায়েন্টের পাঠানো JWT টোকেনটি যাচাই করা হয়। যদি টোকেন বৈধ থাকে, তবে রিকোয়েস্টটি সফল হবে, অন্যথায় একটি Unauthorized মেসেজ ফেরত পাঠানো হবে।

৩. JWT Token ব্যবহার

যখন ক্লায়েন্ট লগইন করে, সার্ভার একটি JWT টোকেন তৈরি করে এবং সেটি ক্লায়েন্টে পাঠায়। ক্লায়েন্ট সেই টোকেনটি রিকোয়েস্ট হেডারে পাঠাবে, উদাহরণস্বরূপ:

৩.১. ক্লায়েন্ট সাইডে টোকেন পাঠানো

fetch('http://localhost:5000/protected', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer <your-jwt-token>'  // এখানে টোকেনটি দিন
  }
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.log('Error:', error));

এখানে, Authorization হেডারে Bearer <your-jwt-token> পাঠিয়ে আপনি সার্ভারের প্রটেক্টেড রাউটে রিকোয়েস্ট পাঠাচ্ছেন।


৪. JWT Secret এবং Environment Variables

এটি খুবই গুরুত্বপূর্ণ যে আপনি JWT Secret নিরাপদে সংরক্ষণ করেন। এটি সাধারণত .env ফাইলে রাখা হয়, যেটি .gitignore ফাইলে অন্তর্ভুক্ত করা উচিত যাতে এটি সোর্স কোডে চলে না যায়।

.env ফাইল উদাহরণ:

JWT_SECRET=my_super_secret_key

এবং এই ভ্যালু ব্যবহার করতে:

dotenv.config();
const JWT_SECRET = process.env.JWT_SECRET;

৫. JWT Expiry

JWT-তে একটি এক্সপিরেশন টাইম থাকতে পারে, যেমন: expiresIn: '1h'। এর মাধ্যমে টোকেনটি একটি নির্দিষ্ট সময় পরে স্বয়ংক্রিয়ভাবে অকার্যকর হয়ে যাবে। এক্ষেত্রে, ব্যবহারকারীকে আবার লগইন করতে হতে পারে বা Refresh Token ব্যবহারের মাধ্যমে নতুন টোকেন রিকোয়েস্ট করা যেতে পারে।


সারাংশ

ExpressJS-এ JWT (JSON Web Token) ব্যবহারের মাধ্যমে আপনি একটি সুরক্ষিত অথেন্টিকেশন সিস্টেম তৈরি করতে পারেন। এই প্রক্রিয়ায় ব্যবহারকারী প্রথমে লগইন করে একটি JWT টোকেন পান, যা পরবর্তী রিকোয়েস্টে ব্যবহৃত হয়। jsonwebtoken প্যাকেজ ব্যবহার করে JWT তৈরি ও যাচাই করা সহজ হয়ে যায়। পাসওয়ার্ড নিরাপদ রাখার জন্য bcryptjs ব্যবহার করা হয়, এবং dotenv প্যাকেজের মাধ্যমে নিরাপদে পরিবেশগত পরিবর্তনশীল সংরক্ষণ করা যায়। JWT ব্যবহার করলে সার্ভার সেশন ম্যানেজমেন্ট থেকে মুক্ত থাকে এবং স্টেটলেস অথেন্টিকেশন বাস্তবায়ন করা যায়।

Content added By

JWT (JSON Web Token) কি?

JWT (JSON Web Token) হল একটি কমপ্যাক্ট এবং URL-safe পদ্ধতি যা দুটি পক্ষের মধ্যে তথ্য নিরাপদভাবে পাঠানোর জন্য ব্যবহৃত হয়। এটি মূলত ব্যবহারকারীর সেশন তথ্য, অথেনটিকেশন, এবং অথোরাইজেশন টোকেন হিসেবে ব্যবহৃত হয়। JWT-তে তিনটি অংশ থাকে:

  1. Header:
    • Header সাধারণত দুটি অংশ নিয়ে গঠিত:
      • alg: এলগরিদম যেমন HMAC SHA256 বা RSA।
      • typ: টোকেনের প্রকার, সাধারণত JWT
  2. Payload:
    • Payload অংশে থাকা তথ্য, যেমন ব্যবহারকারীর আইডি, নাম, বা অন্যান্য কাস্টম ডেটা। এটি "claims" নামে পরিচিত। Claims বিভিন্ন ধরনের হতে পারে:
      • Registered claims: যেমন iss (issuer), exp (expiration time), sub (subject), aud (audience)।
      • Public claims: যা কোন সুনির্দিষ্ট মান দিয়ে যুক্ত হতে পারে, যেমন ব্যবহারকারী আইডি।
      • Private claims: কাস্টম ডেটা যা শুধুমাত্র উক্ত অ্যাপ্লিকেশনের মধ্যে ভাগ করা হয়।
  3. Signature:
    • Signature অংশটি Header এবং Payload এর মধ্যকার নিরাপত্তা নিশ্চিত করার জন্য ব্যবহার করা হয়। এটি হ্যাশ করা হয় একটি সিক্রেট কীগুলি ব্যবহার করে।
    • উদাহরণ হিসেবে, যদি আপনি HMAC SHA256 ব্যবহার করেন, তবে এটি base64UrlEncode(Header) + "." + base64UrlEncode(Payload) এবং একটি সিক্রেট কীগুলির মাধ্যমে হ্যাশ করা হয়।
    • এটি যেকোনো পরিবর্তন শনাক্ত করতে সহায়তা করে, কারণ কোনো পরিবর্তন হলে Signature আর মেলেনা।

JWT টোকেনের গঠন:

HEADER.PAYLOAD.SIGNATURE

JWT কিভাবে কাজ করে?

JWT সাধারণত অথেনটিকেশন ও অথোরাইজেশনের জন্য ব্যবহৃত হয়। একবার ব্যবহারকারী লগইন করলে, একটি JWT টোকেন তৈরি করা হয় যা সার্ভার থেকে ক্লায়েন্টে পাঠানো হয়। এই টোকেনটি পরবর্তী রিকোয়েস্টে ব্যবহারকারীকে সঠিকভাবে অথেনটিকেট বা অথোরাইজ করতে ব্যবহৃত হয়।

১. অথেনটিকেশন প্রক্রিয়া:

  1. ব্যবহারকারী লগইন করে:
    • ব্যবহারকারী তার ক্রিডেনশিয়াল (ইউজারনেম/পাসওয়ার্ড) পাঠায় সার্ভারে।
  2. JWT টোকেন তৈরি:
    • সার্ভার ক্রিডেনশিয়াল যাচাইয়ের পর, একটি JWT টোকেন তৈরি করে এবং ব্যবহারকারীকে পাঠায়।
  3. ব্যবহারকারী টোকেন গ্রহণ করে:
    • টোকেনটি ব্যবহারকারী তার ব্রাউজারে (বা অ্যাপ্লিকেশনের স্থানীয় স্টোরেজে) সংরক্ষণ করে।
  4. ভবিষ্যত রিকোয়েস্টে টোকেন পাঠানো:
    • পরবর্তী যেকোনো রিকোয়েস্টে, ব্যবহারকারী ঐ JWT টোকেনটিকে Authorization হেডারে Bearer টোকেন হিসেবে পাঠায়।
  5. টোকেন যাচাই:
    • সার্ভার টোকেনটি গ্রহণ করে এবং সেটির সিগনেচার যাচাই করে নিশ্চিত করে যে টোকেনটি বৈধ ও অপরিবর্তিত।

২. অথোরাইজেশন প্রক্রিয়া:

  1. টোকেনের মধ্যে তথ্য:
    • JWT-র মধ্যে থাকা Claims (যেমন sub, role, ইত্যাদি) ব্যবহার করে সার্ভার নিশ্চিত করে যে ব্যবহারকারী নির্দিষ্ট রিসোর্সে অ্যাক্সেস পাবে কিনা।
  2. টোকেনের মেয়াদ:
    • JWT-তে সাধারণত একটি exp (expiration) claim থাকে, যা টোকেনের মেয়াদ নির্ধারণ করে। যখন টোকেনের মেয়াদ শেষ হয়ে যায়, তখন ব্যবহারকারীকে আবার লগইন করতে বলা হয়।

JWT এর সুবিধা:

  1. স্ট্যাটলেস (Stateless):
    • JWT টোকেন সার্ভারের উপর কোনো স্টোরেজের প্রয়োজন নেই। সার্ভার শুধুমাত্র টোকেন যাচাই করে। এর ফলে সার্ভার স্কেলেবল এবং উন্নত পারফরম্যান্স পায়।
  2. একই টোকেন ব্যবহার করা যায়:
    • একবার ব্যবহারকারীর লগইন টোকেন তৈরি হলে, সেটি বহুবিধ রিকোয়েস্টে ব্যবহার করা যেতে পারে।
  3. নিরাপত্তা:
    • JWT সিগনেচার হ্যাশ করার মাধ্যমে নিরাপদ থাকে। এছাড়া, এটি HTTPS এর মাধ্যমে পাঠানো হলে, টোকেনটি আরো নিরাপদ হয়ে ওঠে।
  4. কাস্টম ক্লেইম ব্যবহার:
    • JWT-তে আপনি কাস্টম তথ্য (যেমন ব্যবহারকারীর ভূমিকা, অনুমতি) অন্তর্ভুক্ত করতে পারেন, যা সার্ভার বা API কে ইজি অথোরাইজেশন করতে সাহায্য করে।

ExpressJS এ JWT ইন্টিগ্রেশন

এখানে ExpressJS-এ JWT ব্যবহারের প্রাথমিক উদাহরণ দেখানো হলো:

১. JWT টোকেন তৈরি এবং ক্লায়েন্টে পাঠানো:

const jwt = require('jsonwebtoken');
const express = require('express');
const app = express();
const PORT = 3000;

app.use(express.json());

const SECRET_KEY = 'your_secret_key';

// লগইন রাউট, যেখানে JWT টোকেন তৈরি করা হয়
app.post('/login', (req, res) => {
  const { username, password } = req.body;

  // সাধারণত এখানে ডাটাবেস যাচাই করা হয়
  if (username === 'user' && password === 'password') {
    // টোকেন তৈরি করা
    const token = jwt.sign({ username }, SECRET_KEY, { expiresIn: '1h' });
    res.json({ token });
  } else {
    res.status(401).send('Unauthorized');
  }
});

// সুরক্ষিত রাউট, যেখানে JWT যাচাই করা হয়
app.get('/protected', (req, res) => {
  const token = req.headers['authorization']?.split(' ')[1]; // "Bearer <token>" থেকে টোকেন আলাদা করা

  if (!token) {
    return res.status(403).send('Token is required');
  }

  // JWT টোকেন যাচাই করা
  jwt.verify(token, SECRET_KEY, (err, decoded) => {
    if (err) {
      return res.status(403).send('Invalid token');
    }

    res.json({ message: 'This is a protected route', user: decoded.username });
  });
});

app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});

এখানে, /login রাউটের মাধ্যমে ব্যবহারকারী লগইন করে এবং একটি JWT টোকেন পায়। পরে, /protected রাউটে, ব্যবহারকারী তার JWT টোকেনের মাধ্যমে অ্যাক্সেস পায়, যা সার্ভার দ্বারা যাচাই করা হয়।


সারাংশ

JWT (JSON Web Token) হল একটি সিকিউর এবং সহজ পদ্ধতি, যা ব্যবহারকারীর অথেনটিকেশন ও অথোরাইজেশন তথ্যকে নিরাপদভাবে এক জায়গা থেকে আরেক জায়গায় প্রেরণ করতে সাহায্য করে। ExpressJS-এ JWT ব্যবহারের মাধ্যমে আপনি স্ট্যাটলেস অথেনটিকেশন প্রক্রিয়া তৈরি করতে পারেন, যেখানে ব্যবহারকারী একবার লগইন করে একটি টোকেন পায়, এবং পরবর্তীতে সেই টোকেনের মাধ্যমে সুরক্ষিত রিসোর্স অ্যাক্সেস করতে পারে।

Content added By

JWT (JSON Web Token) একটি ওপেন স্ট্যান্ডার্ড যা নিরাপদে তথ্য আদান-প্রদান করতে ব্যবহৃত হয়। এটি সাধারণত Authentication (অথেন্টিকেশন) এবং Authorization (অথরাইজেশন) এর জন্য ব্যবহৃত হয়। ExpressJS অ্যাপ্লিকেশনে JWT টোকেন জেনারেট এবং যাচাই করার মাধ্যমে ব্যবহারকারীর লগইন সিস্টেম তৈরি করা যায়। এখানে, আমরা দেখব কিভাবে ExpressJS এ JWT টোকেন জেনারেট করা এবং যাচাই করা যায়।


১. JWT টোকেন জেনারেট করার জন্য প্রয়োজনীয় প্যাকেজ ইনস্টল করা

প্রথমে, JWT টোকেন তৈরি এবং যাচাই করার জন্য jsonwebtoken প্যাকেজটি ইনস্টল করতে হবে।

npm install jsonwebtoken

২. JWT টোকেন জেনারেট করা

JWT টোকেন তৈরি করার জন্য, একটি secret key ব্যবহার করা হয় যা টোকেন সাইন করার জন্য ব্যবহৃত হয়। নিচে একটি সিম্পল উদাহরণ দেওয়া হলো কিভাবে টোকেন তৈরি করা হয়:

২.১. JWT টোকেন জেনারেট করার উদাহরণ

const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
const port = 3000;

// Secret key (এটি নিরাপদে সংরক্ষণ করুন)
const SECRET_KEY = 'yourSecretKey';

// Middleware to parse JSON body
app.use(express.json());

// JWT টোকেন জেনারেট করার রাউট
app.post('/login', (req, res) => {
  const { username, password } = req.body;

  // এখানে শুধু উদাহরণের জন্য একটি সিম্পল চেক করা হচ্ছে
  if (username === 'admin' && password === 'password') {
    // ইউজার ভ্যালিড হলে টোকেন জেনারেট করা
    const token = jwt.sign({ username }, SECRET_KEY, { expiresIn: '1h' });

    res.json({ token });
  } else {
    res.status(401).send('Invalid credentials');
  }
});

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});

এখানে, /login রাউটে POST রিকোয়েস্ট পাঠালে যদি ব্যবহারকারীর username এবং password সঠিক হয়, তাহলে একটি JWT টোকেন জেনারেট করা হবে। টোকেনটি ১ ঘণ্টা সময়ের জন্য বৈধ থাকবে (expiresIn: '1h')।


৩. JWT টোকেন যাচাই করা

JWT টোকেন যাচাই করার জন্য আমরা middleware ব্যবহার করতে পারি। এটি ব্যবহারকারী যেসব রিকোয়েস্ট পাঠাবে, তাদের মধ্যে টোকেনটি যাচাই করবে এবং প্রমাণিত হলে রিকোয়েস্ট চালাতে দিবে।

৩.১. JWT টোকেন যাচাই করার উদাহরণ

// Middleware for JWT verification
function verifyToken(req, res, next) {
  // টোকেন হেডারে থাকা উচিত
  const token = req.headers['authorization'];

  if (!token) {
    return res.status(403).send('Token is required');
  }

  // "Bearer <token>" ফরম্যাটে টোকেন থাকে, তাই "Bearer" অংশটি বাদ দিয়ে টোকেনটি বের করে নেয়া হচ্ছে
  const tokenWithoutBearer = token.split(' ')[1];

  // JWT টোকেন যাচাই করা
  jwt.verify(tokenWithoutBearer, SECRET_KEY, (err, decoded) => {
    if (err) {
      return res.status(401).send('Invalid token');
    }
    // টোকেন সঠিক হলে decoded ডেটা `req.user` এ রাখা হবে
    req.user = decoded;
    next();  // রিকোয়েস্ট পরবর্তী হ্যান্ডলার বা রাউটকে যেতে দিবে
  });
}

// Protected route example
app.get('/profile', verifyToken, (req, res) => {
  res.json({ message: 'Welcome to your profile', user: req.user });
});

এখানে verifyToken middleware টোকেন যাচাই করে এবং যদি টোকেনটি বৈধ হয়, তাহলে req.user এ decoded তথ্য পাস করা হয়, যা পরবর্তী রাউট হ্যান্ডলারদের জন্য উপলব্ধ হয়। যদি টোকেন বৈধ না হয়, তবে 401 Unauthorized এরর রেসপন্স প্রদান করা হয়।


৪. JWT টোকেনের সাথে Protected Route

একটি protected রাউট তৈরি করতে, যেখানে শুধুমাত্র JWT টোকেন সহকারে প্রবেশ করা যাবে, আপনাকে কেবল verifyToken middleware ব্যবহার করতে হবে।

৪.১. Protected Route উদাহরণ

app.get('/dashboard', verifyToken, (req, res) => {
  res.json({
    message: 'Welcome to the dashboard',
    user: req.user // Decoded user information from token
  });
});

এখানে, /dashboard রাউটটি শুধুমাত্র তখনই অ্যাক্সেস করা যাবে যখন সঠিক JWT টোকেন সাথে পাঠানো হবে। যদি টোকেন সঠিক হয়, তবে ড্যাশবোর্ডের ডেটা দেখা যাবে; নতুবা 401 Unauthorized এরর রিটার্ন করা হবে।


৫. JWT টোকেনের সুবিধা ও সুরক্ষা

  • Stateless Authentication: JWT-তে কোনো স্টোরেজ প্রয়োজন হয় না, এটি ক্লায়েন্টের সাইটে রাখা হয় এবং সমস্ত ইনফরমেশন টোকেনের মধ্যে সংরক্ষিত থাকে।
  • Security: টোকেনটি sign করা থাকে, এবং secret key দিয়ে ভ্যালিডেশন করা হয়, যা এর নিরাপত্তা নিশ্চিত করে।
  • Expiry: JWT-তে নির্দিষ্ট সময়ের জন্য বৈধতা থাকে, ফলে নির্দিষ্ট সময় পর টোকেনটি অবৈধ হয়ে যায়, এবং নতুন টোকেন নিতে হবে।

সারাংশ

ExpressJS এ JWT টোকেন জেনারেট এবং যাচাই করার মাধ্যমে আপনি একটি সুরক্ষিত অথেন্টিকেশন সিস্টেম তৈরি করতে পারেন। jsonwebtoken প্যাকেজ ব্যবহার করে JWT টোকেন সহজেই তৈরি এবং যাচাই করা সম্ভব। টোকেন সঠিক হলে, ব্যবহারকারীরা অ্যাপ্লিকেশনের সুরক্ষিত রাউটগুলোতে প্রবেশ করতে পারবে। এর মাধ্যমে আপনি সহজেই একটি RESTful API তৈরি করতে পারবেন যা নিরাপদ এবং কার্যকরী।

Content added By

Token Expiration এবং Refresh Tokens হল আধুনিক ওয়েব অ্যাপ্লিকেশনগুলিতে নিরাপত্তা বজায় রাখার গুরুত্বপূর্ণ উপাদান। JWT (JSON Web Tokens) সাধারণত নির্দিষ্ট সময়ের জন্য বৈধ থাকে, অর্থাৎ কিছু সময় পর token expiration ঘটে। যখন token মেয়াদোত্তীর্ণ হয়ে যায়, তখন ব্যবহারকারীকে পুনরায় লগইন করতে বলা হয়। তবে Refresh Tokens ব্যবহার করে, আমরা মেয়াদোত্তীর্ণ টোকেনের পরিবর্তে নতুন টোকেন প্রদান করতে পারি, যাতে ইউজার আবার লগইন না করতে হয়।

ExpressJS-এ token expiration এবং refresh tokens ব্যবস্থাপনা সহজে বাস্তবায়ন করা যায়।


১. Token Expiration (টোকেন মেয়াদোত্তীর্ণ হওয়া)

JWT এর মাধ্যমে authentication করা হলে, আপনি টোকেনের মেয়াদ নির্ধারণ করতে পারেন। সাধারণত একটি JWT টোকেন যখন তৈরি করা হয়, তখন তার মেয়াদ নির্ধারণ করা হয়, যেমন: 1 ঘণ্টা, 1 দিন, বা কোনো নির্দিষ্ট সময়ের জন্য। মেয়াদ শেষ হলে, টোকেনটি আর বৈধ থাকে না এবং ইউজারকে পুনরায় authentication করতে বলা হয়।

১.১. JWT Token Expiration সেট করা

JWT টোকেনের expiration সময় নির্ধারণ করতে expiresIn প্যারামিটার ব্যবহার করা হয়।

কোড উদাহরণ:
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
const port = 3000;

const secretKey = 'secretKey';
const users = [
  { id: 1, username: 'john', password: 'password123' }
];

// লগইন রাউট - JWT টোকেন তৈরি করা
app.post('/login', (req, res) => {
  const { username, password } = req.body;
  const user = users.find(u => u.username === username && u.password === password);

  if (user) {
    // JWT টোকেন তৈরি, এক ঘণ্টার জন্য মেয়াদোত্তীর্ণ হবে
    const token = jwt.sign({ userId: user.id }, secretKey, { expiresIn: '1h' });
    res.json({ token });
  } else {
    res.status(401).send('Invalid credentials');
  }
});

// প্রোটেক্টেড রাউট - টোকেন যাচাই
app.get('/protected', (req, res) => {
  const token = req.headers['authorization'];

  if (!token) {
    return res.status(403).send('Access denied');
  }

  // টোকেন যাচাই করা
  jwt.verify(token, secretKey, (err, decoded) => {
    if (err) {
      return res.status(403).send('Token expired or invalid');
    }
    res.send(`Protected content for user ID: ${decoded.userId}`);
  });
});

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});

এখানে:

  • টোকেনের মেয়াদ 1 ঘণ্টা (expiresIn: '1h') হিসেবে নির্ধারণ করা হয়েছে।
  • যদি টোকেনের মেয়াদ শেষ হয়ে যায়, তবে jwt.verify ফাংশন err রিটার্ন করবে এবং "Token expired or invalid" বার্তা প্রদান করবে।

২. Refresh Tokens (রিফ্রেশ টোকেন)

Refresh Tokens হল দীর্ঘ মেয়াদী টোকেন যা মূলত ব্যবহারকারীর দীর্ঘ মেয়াদী authentication এর জন্য ব্যবহৃত হয়। যখন একটি JWT টোকেনের মেয়াদ শেষ হয়ে যায়, তখন ইউজারকে পুনরায় লগইন করতে না বলে, একটি Refresh Token ব্যবহার করে নতুন JWT টোকেন তৈরি করা হয়।

২.১. Refresh Token সিস্টেম

Refresh Token সাধারণত JWT টোকেনের তুলনায় বেশি সময়ের জন্য বৈধ থাকে (যেমন: কয়েক দিন বা মাস)। যখন JWT টোকেনের মেয়াদ শেষ হয়, তখন রিফ্রেশ টোকেন ব্যবহার করে নতুন JWT টোকেন তৈরি করা হয়।

ইনস্টলেশন:
npm install jsonwebtoken
কোড উদাহরণ:
const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
const port = 3000;

const secretKey = 'secretKey';
const refreshSecretKey = 'refreshSecretKey';  // রিফ্রেশ টোকেনের জন্য আলাদা সিক্রেট
const users = [
  { id: 1, username: 'john', password: 'password123' }
];

// রিফ্রেশ টোকেন ডাটাবেস (যতটুকু দীর্ঘকালীন থাকতে হবে)
const refreshTokens = [];

// লগইন রাউট - JWT এবং Refresh Token তৈরি করা
app.post('/login', (req, res) => {
  const { username, password } = req.body;
  const user = users.find(u => u.username === username && u.password === password);

  if (user) {
    // JWT টোকেন তৈরি, 1 ঘণ্টার জন্য মেয়াদোত্তীর্ণ হবে
    const accessToken = jwt.sign({ userId: user.id }, secretKey, { expiresIn: '1h' });

    // রিফ্রেশ টোকেন তৈরি, 7 দিন মেয়াদী
    const refreshToken = jwt.sign({ userId: user.id }, refreshSecretKey, { expiresIn: '7d' });

    // রিফ্রেশ টোকেন ডাটাবেসে সংরক্ষণ করা
    refreshTokens.push(refreshToken);

    res.json({ accessToken, refreshToken });
  } else {
    res.status(401).send('Invalid credentials');
  }
});

// রিফ্রেশ টোকেন দিয়ে নতুন JWT টোকেন তৈরি
app.post('/token', (req, res) => {
  const { refreshToken } = req.body;

  if (!refreshToken) {
    return res.status(401).send('Refresh token required');
  }

  if (!refreshTokens.includes(refreshToken)) {
    return res.status(403).send('Invalid refresh token');
  }

  // রিফ্রেশ টোকেন যাচাই করা
  jwt.verify(refreshToken, refreshSecretKey, (err, decoded) => {
    if (err) {
      return res.status(403).send('Invalid refresh token');
    }

    // নতুন অ্যাক্সেস টোকেন তৈরি
    const accessToken = jwt.sign({ userId: decoded.userId }, secretKey, { expiresIn: '1h' });
    res.json({ accessToken });
  });
});

// প্রোটেক্টেড রাউট - JWT টোকেন যাচাই
app.get('/protected', (req, res) => {
  const token = req.headers['authorization'];

  if (!token) {
    return res.status(403).send('Access denied');
  }

  // টোকেন যাচাই করা
  jwt.verify(token, secretKey, (err, decoded) => {
    if (err) {
      return res.status(403).send('Token expired or invalid');
    }
    res.send(`Protected content for user ID: ${decoded.userId}`);
  });
});

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});

এখানে:

  • ইউজার লগইন করলে, আমরা দুটি টোকেন তৈরি করি: Access Token (JWT) এবং Refresh Token
  • Access Token এর মেয়াদ 1 ঘণ্টা, এবং Refresh Token এর মেয়াদ 7 দিন।
  • যখন Access Token এর মেয়াদ শেষ হয়ে যায়, তখন Refresh Token ব্যবহার করে নতুন Access Token তৈরি করা হয়।

৩. Refresh Tokens ব্যবস্থাপনার নিরাপত্তা

  • Refresh Token সাধারণত দীর্ঘ মেয়াদী হয়, তাই এটি সুরক্ষিতভাবে সংরক্ষণ করা জরুরি। এটি সাধারনত ডাটাবেসে বা Secure HTTPOnly Cookies এ সংরক্ষণ করা হয়।
  • Refresh Tokens এর ওপর অতিরিক্ত সুরক্ষা নিশ্চিত করতে, আপনি revocation mechanism তৈরি করতে পারেন, অর্থাৎ যদি ইউজার লগআউট করে বা তার রিফ্রেশ টোকেন বাতিল করা হয়, তবে সেটি আর ব্যবহৃত হতে পারবে না।

সারাংশ

Token Expiration এবং Refresh Tokens ব্যবস্থাপনা একটি গুরুত্বপূর্ণ নিরাপত্তা ব্যবস্থা, যা ExpressJS অ্যাপ্লিকেশনকে নিরাপদ রাখতে সাহায্য করে। যখন JWT টোকেনের মেয়াদ শেষ হয়, তখন Refresh Token ব্যবহার করে নতুন টোকেন তৈরি করা হয়, যাতে ইউজারকে পুনরায় লগইন না করতে হয়। এই ব্যবস্থাটি আধুনিক ওয়েব অ্যাপ্লিকেশনগুলির জন্য নিরাপত্তা বৃদ্ধি করতে গুরুত্বপূর্ণ এবং ব্যবহারকারীর অভিজ্ঞতা উন্নত করতে সহায়ক।

Content added By

JWT (JSON Web Token) একটি স্ট্যান্ডার্ড যা সার্ভার এবং ক্লায়েন্টের মধ্যে নিরাপদভাবে ডেটা আদান-প্রদান করার জন্য ব্যবহৃত হয়। JWT-এর মাধ্যমে API-র নিরাপত্তা নিশ্চিত করা একটি জনপ্রিয় পদ্ধতি, বিশেষত RESTful API-তে। ExpressJS-এ JWT ব্যবহার করে API নিরাপত্তা কনফিগার করতে হলে, ইউজারের Authentication এবং Authorization পরিচালনা করতে হয়, যেখানে JWT ইউজার আইডেন্টিফিকেশন এবং এক্সেস কন্ট্রোলের কাজ করে।


JWT কী?

JWT একটি কমপ্যাক্ট, URL-safe টোকেন যা সার্ভার এবং ক্লায়েন্টের মধ্যে তথ্য নিরাপদভাবে পাঠাতে ব্যবহৃত হয়। JWT সাধারণত তিনটি অংশে বিভক্ত থাকে:

  1. Header: টোকেনের ধরণ এবং এনক্রিপশন অ্যালগরিদম সম্পর্কে তথ্য।
  2. Payload: ব্যবহারকারী সম্পর্কিত তথ্য (যেমন, ইউজার আইডি, রোল, অথবা অন্যান্য ডেটা)।
  3. Signature: হেডার এবং পে-লোড সিগনেচার করতে ব্যবহৃত হয়, যাতে টোকেনটি নিরাপদ থাকে এবং পরিবর্তন করা না যায়।

JWT-এর মাধ্যমে API সিকিউরিটি কনফিগার করার জন্য, প্রধানত দুটি প্রক্রিয়া অনুসরণ করা হয়:

  1. Authentication: ইউজারের লগইন প্রক্রিয়া এবং JWT টোকেন তৈরি করা।
  2. Authorization: ইউজার টোকেন দিয়ে API রিকোয়েস্ট যাচাই এবং অনুমতি দেওয়া।

JWT ইনস্টল করা

প্রথমে, JWT-কে ExpressJS প্রকল্পে ব্যবহার করার জন্য, jsonwebtoken লাইব্রেরিটি ইনস্টল করতে হবে:

npm install jsonwebtoken

এছাড়া, express এবং body-parser ইনস্টল করা থাকলে ভালো, তবে ExpressJS এ body-parser সাধারণত বিল্ট-ইন থাকে।


JWT এর মাধ্যমে API Security কনফিগার করা

এখন আমরা একটি সাধারণ উদাহরণ দেখব, যেখানে ExpressJS এবং JWT ব্যবহার করে API সিকিউরিটি কনফিগার করা হবে। এখানে ইউজারের লগইন, JWT টোকেন তৈরি এবং টোকেন যাচাই করার প্রক্রিয়া দেখানো হবে।

১. ইউজার লগইন এবং JWT টোকেন তৈরি করা

const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
const port = 3000;

app.use(express.json());

// Dummy user database
const users = [
  { id: 1, username: 'user1', password: 'password123' },
  { id: 2, username: 'user2', password: 'password456' }
];

// Secret key for signing JWT
const secretKey = 'your-secret-key';

// Login route to generate JWT token
app.post('/login', (req, res) => {
  const { username, password } = req.body;
  
  // Find user by username and password
  const user = users.find(u => u.username === username && u.password === password);
  
  if (!user) {
    return res.status(401).send('Invalid credentials');
  }
  
  // Create JWT token
  const token = jwt.sign({ id: user.id, username: user.username }, secretKey, { expiresIn: '1h' });
  
  // Send the token to the client
  res.json({ token });
});

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});

এখানে:

  • /login রাউটে ইউজার নাম এবং পাসওয়ার্ড চেক করা হয়। সঠিক হলে, একটি JWT টোকেন তৈরি করা হয়।
  • টোকেনটি jwt.sign() ফাংশন ব্যবহার করে তৈরি করা হয়, যেখানে ইউজারের তথ্য এবং সিক্রেট কী ব্যবহার করা হয়।
  • টোকেনটি 1 ঘণ্টার জন্য ভ্যালিড থাকবে (এটি expiresIn দিয়ে নির্ধারণ করা হয়েছে)।

২. Protected Route এবং Token যাচাই করা

API সিকিউর করতে, আপনাকে JWT টোকেন যাচাই করার জন্য একটি middleware তৈরি করতে হবে। এটি নিশ্চিত করবে যে রিকোয়েস্টটি সঠিকভাবে অথেনটিকেটেড।

// Middleware to verify JWT token
const verifyToken = (req, res, next) => {
  const token = req.headers['authorization'];

  if (!token) {
    return res.status(403).send('Token is required');
  }

  // Remove 'Bearer ' prefix if present
  const tokenWithoutBearer = token.split(' ')[1];

  // Verify the token
  jwt.verify(tokenWithoutBearer, secretKey, (err, decoded) => {
    if (err) {
      return res.status(403).send('Invalid or expired token');
    }

    // Save user information in request for further use
    req.user = decoded;
    next();
  });
};

// Protected route, requires valid JWT token
app.get('/protected', verifyToken, (req, res) => {
  res.send(`Hello, ${req.user.username}. You have access to this protected resource.`);
});

এখানে:

  • verifyToken middleware রিকোয়েস্টের Authorization হেডার থেকে JWT টোকেন গ্রহণ করে।
  • টোকেনটি jwt.verify() ফাংশন দিয়ে যাচাই করা হয়। টোকেনটি যদি বৈধ হয়, তবে ইউজারের তথ্য req.user-এ রাখা হয়, যা পরবর্তী রাউট হ্যান্ডলারগুলোতে ব্যবহৃত হতে পারে।
  • যদি টোকেনটি অনুপস্থিত বা অবৈধ হয়, তবে 403 Forbidden রেসপন্স পাঠানো হয়।

৩. Full Example: JWT Authentication ও Authorization

const express = require('express');
const jwt = require('jsonwebtoken');
const app = express();
const port = 3000;

app.use(express.json());

const users = [
  { id: 1, username: 'user1', password: 'password123' },
  { id: 2, username: 'user2', password: 'password456' }
];

const secretKey = 'your-secret-key';

// Login route to generate JWT token
app.post('/login', (req, res) => {
  const { username, password } = req.body;
  
  const user = users.find(u => u.username === username && u.password === password);
  
  if (!user) {
    return res.status(401).send('Invalid credentials');
  }
  
  const token = jwt.sign({ id: user.id, username: user.username }, secretKey, { expiresIn: '1h' });
  
  res.json({ token });
});

// Middleware to verify JWT token
const verifyToken = (req, res, next) => {
  const token = req.headers['authorization'];
  if (!token) {
    return res.status(403).send('Token is required');
  }

  const tokenWithoutBearer = token.split(' ')[1];
  jwt.verify(tokenWithoutBearer, secretKey, (err, decoded) => {
    if (err) {
      return res.status(403).send('Invalid or expired token');
    }
    req.user = decoded;
    next();
  });
};

// Protected route, requires JWT token
app.get('/protected', verifyToken, (req, res) => {
  res.send(`Hello, ${req.user.username}. You have access to this protected resource.`);
});

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});

JWT এর মাধ্যমে API Security কনফিগার করার উপকারিতা

  • Scalability: JWT স্ট্যাটলেস, অর্থাৎ সার্ভারে কোনো session স্টোর করা লাগে না, যা API সিস্টেমকে আরো স্কেলেবল করে।
  • Security: JWT একটি সিক্রেট কী দ্বারা সাইন করা হয়, তাই টোকেনটি নিরাপদ থাকে এবং এতে কোনো পরিবর্তন করলে তা ধরা পড়ে।
  • Performance: JWT দ্রুত এবং কমপ্যাক্ট হওয়ায়, এটি বেশি ট্রাফিক হ্যান্ডল করার জন্য উপযোগী।

সারাংশ

ExpressJS-এ JWT (JSON Web Token) এর মাধ্যমে API সিকিউরিটি কনফিগার করা একটি অত্যন্ত কার্যকরী পদ্ধতি। আপনি JWT টোকেন ব্যবহার করে ইউজার Authentication পরিচালনা করতে পারেন এবং API রিকোয়েস্টে Authorization চেক করতে পারেন। JWT স্ট্যাটলেস এবং নিরাপদ হওয়ায় এটি API সিকিউরিটির জন্য একটি জনপ্রিয় এবং স্কেলেবল পদ্ধতি।

Content added By
Promotion

Are you sure to start over?

Loading...