TypeScript-এ `Cookie`
এই প্রবন্ধে TypeScript-এ Cookie ব্যাখ্যা করা হয়েছে।
আমরা ব্রাউজার ও সার্ভার—উভয় ক্ষেত্রেই কুকি নিরাপদ ও নির্ভরযোগ্যভাবে ব্যবহারের বাস্তবধর্মী প্যাটার্নগুলো আলোচনা করি।
YouTube Video
TypeScript-এ Cookie
কুকির মৌলিক ধারণা
কুকি হল ক্লায়েন্টে ছোট স্ট্রিং (name=value জুটি) সংরক্ষণের একটি প্রক্রিয়া, যা Set-Cookie HTTP হেডার বা document.cookie এর মাধ্যমে তৈরি হয়। নিরাপত্তা অ্যাট্রিবিউট (HttpOnly, Secure, SameSite, ইত্যাদি) দিয়ে তাদের আচরণ নিয়ন্ত্রণ করা যায়।
ব্রাউজারে মৌলিক অপারেশন: document.cookie
নিচে ব্রাউজারে কুকি লেখার একটি ন্যূনতম উদাহরণ দেওয়া হলো। document.cookie-এ একটি স্ট্রিং যোগ করে কুকি তৈরি করুন।
1// Set a simple cookie that expires in 7 days.
2// Note: Comments are in English per the user's preference.
3const setSimpleCookie = (name: string, value: string) => {
4 const days = 7;
5 const expires = new Date(Date.now() + days * 86400_000).toUTCString();
6 // name=value; Expires=...; Path=/
7 document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}; Expires=${expires}; Path=/`;
8};
9
10setSimpleCookie('theme', 'dark');- এই কোডটি এমন একটি কুকি তৈরি করে যা ৭ দিনে মেয়াদোত্তীর্ণ হয়। ব্রাউজার সাইডে ব্যবহার করা সহজ, কিন্তু
HttpOnlyসেট করা যায় না বলে সংবেদনশীল তথ্য সংরক্ষণ করা থেকে বিরত থাকা উচিত।
কুকি পড়া (ব্রাউজার)
নিচের ফাংশনটি একটি হেলপার, যা document.cookie থেকে নির্দিষ্ট নামের কুকির মান বের করে। document.cookie একটি স্ট্রিং হিসেবে ফেরত দেয়, যেখানে আইটেমগুলো সেমিকোলন ও স্পেস ('; ') দিয়ে আলাদা করা থাকে। তাই আমরা স্ট্রিংটি ভাগ করে কাঙ্ক্ষিত কুকিটি খুঁজে নিই।
1// Parse document.cookie and return value for given name or null if not found.
2const getCookie = (name: string): string | null => {
3 const cookies = document.cookie ? document.cookie.split('; ') : [];
4 for (const cookie of cookies) {
5 const [k, ...rest] = cookie.split('=');
6 const v = rest.join('=');
7 if (decodeURIComponent(k) === name) {
8 return decodeURIComponent(v);
9 }
10 }
11 return null;
12};
13
14// Example usage:
15const theme = getCookie('theme'); // => "dark" if set
16console.log('theme cookie:', theme);- এই ফাংশনটি নিরাপদে তুলনা ও বের করার জন্য কুকির নাম এবং মান—উভয়ই ডিকোড করে। এটি ডুপ্লিকেট কুকি নাম এবং এনকোড করা বিশেষ অক্ষরও সামলে দেয়, ফলে এটি সরল হলেও রোবাস্ট একটি বাস্তবায়ন।
সিকিউরিটি অ্যাট্রিবিউট বোঝা ও প্রয়োগ
কুকিতে কয়েকটি গুরুত্বপূর্ণ অ্যাট্রিবিউট থাকে; প্রতিটি অ্যাট্রিবিউট নিরাপত্তা এবং আচরণের পরিসর নিয়ন্ত্রণ করে।
HttpOnlyঅ্যাট্রিবিউটটি কুকিকে JavaScript থেকে অ্যাক্সেসযোগ্য হতে দেয় না, ফলে XSS (cross-site scripting) আক্রমণের ঝুঁকি কমাতে সাহায্য করে। মনে রাখবেন, ব্রাউজার পাশ থেকেHttpOnlyসেট করা যায় না।Secureঅ্যাট্রিবিউটটি কুকি শুধু HTTPS-এর মাধ্যমে পাঠানোকে সীমাবদ্ধ করে, যাতে আড়িপাতা ও বিকৃতকরণের ঝুঁকি কমে।SameSiteঅ্যাট্রিবিউটটি নির্ধারণ করে ক্রস-সাইট অনুরোধের সাথে কুকি পাঠানো হবে কি না এবং CSRF (cross-site request forgery) আক্রমণ প্রতিরোধে সাহায্য করে।Pathঅ্যাট্রিবিউটটি কোন কোন রিকোয়েস্ট পাথে কুকি পাঠানো হবে তার পরিসর নির্ধারণ করে, এবংDomainঅ্যাট্রিবিউটটি কোন ডোমেইনে কুকিটি বৈধ তা নির্দিষ্ট করে।ExpiresবাMax-Ageঅ্যাট্রিবিউট সেট করে কুকির মেয়াদ (expiration) নিয়ন্ত্রণ করতে পারেন।
ব্রাউজারে SameSite / Secure যোগ করার উদাহরণ (যা সম্ভব)
HttpOnly ক্লায়েন্ট সাইডে সেট করা যায় না। নিচে ক্লায়েন্ট সাইডে SameSite এবং Secure যোগ করার একটি উদাহরণ দেওয়া হলো। Secure কেবল HTTPS পেজে কার্যকর হয়।
1// Set cookie with SameSite and Secure attributes (Secure only effective over HTTPS).
2const setCookieWithAttributes = (name: string, value: string) => {
3 const maxAge = 60 * 60 * 24 * 7; // 7 days in seconds
4 // Note: HttpOnly cannot be set from JS; set it on server-side when you want to restrict JS access.
5 document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}; `
6 + `Max-Age=${maxAge}; `
7 + `Path=/; `
8 + `SameSite=Lax; `
9 + `Secure`;
10};
11
12setCookieWithAttributes('session_hint', 'true');SameSite=Laxএকটি নিরাপদ ও প্রচলিত পছন্দ। আরও কঠোর সীমাবদ্ধতার জন্যSameSite=Strictব্যবহার করুন, তবে বাইরের সাইট থেকে বৈধ ন্যাভিগেশন কাজ করা বন্ধ হতে পারে।
সার্ভারে কুকি সেট করা (Set-Cookie) (Node / TypeScript)
সার্ভারে আপনি Set-Cookie হেডারের মাধ্যমে HttpOnly যোগ করতে পারেন, তাই সেশন ম্যানেজমেন্ট আদর্শভাবে সার্ভার-সাইডেই করা উচিত। নিচে Node-এর http মডিউল ব্যবহার করার একটি উদাহরণ রয়েছে।
1// A minimal Node HTTP server in TypeScript that sets a secure HttpOnly cookie.
2// This example uses built-in 'crypto' for a random session id.
3import http from 'http';
4import crypto from 'crypto';
5
6const server = http.createServer((req, res) => {
7 if (req.url === '/login') {
8 const sessionId = crypto.randomBytes(16).toString('hex');
9 // Set cookie with HttpOnly, Secure, SameSite and Path
10 // Expires is optional — Max-Age preferred for relative lifetimes.
11 res.setHeader('Set-Cookie', `sid=${sessionId}; `
12 + `HttpOnly; `
13 + `Secure; `
14 + `SameSite=Strict; `
15 + `Path=/; `
16 + `Max-Age=3600`
17 );
18 res.writeHead(302, { Location: '/' });
19 res.end();
20 return;
21 }
22
23 res.writeHead(200, { 'Content-Type': 'text/plain' });
24 res.end('Hello\n');
25});
26
27server.listen(3000, () => {
28 console.log('Server running on http://localhost:3000');
29});- সার্ভার সাইডে
HttpOnlyঅ্যাট্রিবিউট সেট করলে কুকিটি JavaScript থেকে অপ্রাপ্য হয়ে যায়, ফলে XSS (cross-site scripting) আক্রমণের মাধ্যমে এটি চুরি করা কঠিন হয়। অতিরিক্তভাবে,Secureঅ্যাট্রিবিউট যোগ করে কুকি সর্বদা HTTPS-এর মাধ্যমে পাঠালে আড়িপাতা ও বিকৃতকরণ রোধ করা যায় এবং যোগাযোগের নিরাপত্তা বৃদ্ধি পায়।
কুকি সিরিয়ালাইজেশন/পার্সিং ইমপ্লিমেন্টেশন (একটি সার্ভার-সাইড হেল্পার)
নিচে একটি সহজ সার্ভার-সাইড ইউটিলিটি দেওয়া হলো যা একটি Set-Cookie হেডার স্ট্রিং তৈরি করে।
1// Cookie serialization helper for server-side use.
2// Returns a properly formatted Set-Cookie header value.
3type CookieOptions = {
4 path?: string;
5 domain?: string;
6 maxAge?: number;
7 expires?: Date;
8 httpOnly?: boolean;
9 secure?: boolean;
10 sameSite?: 'Strict' | 'Lax' | 'None';
11};
12
13const serializeCookie = (name: string, value: string, opts: CookieOptions = {}): string => {
14 const parts: string[] = [`${encodeURIComponent(name)}=${encodeURIComponent(value)}`];
15
16 if (opts.maxAge != null) parts.push(`Max-Age=${Math.floor(opts.maxAge)}`);
17 if (opts.expires) parts.push(`Expires=${opts.expires.toUTCString()}`);
18 if (opts.domain) parts.push(`Domain=${opts.domain}`);
19 parts.push(`Path=${opts.path ?? '/'}`);
20 if (opts.httpOnly) parts.push('HttpOnly');
21 if (opts.secure) parts.push('Secure');
22 if (opts.sameSite) parts.push(`SameSite=${opts.sameSite}`);
23
24 return parts.join('; ');
25};
26
27// Example usage:
28const headerValue = serializeCookie('uid', 'abc123', {
29 httpOnly: true,
30 secure: true,
31 sameSite: 'Lax',
32 maxAge: 3600
33});
34console.log(headerValue);
35// => "uid=abc123; Max-Age=3600; Path=/; HttpOnly; Secure; SameSite=Lax"
- এই ইউটিলিটি কাস্টম সার্ভারে
Set-Cookieতৈরি করার ভিত্তি হিসেবে কাজ করে। লাইব্রেরিগুলো আরও অনেক এজ কেস সামলাতে পারে।
সিগনেচার (HMAC) দিয়ে ট্যাম্পারিং প্রতিরোধ
গুরুত্বপূর্ণ মান সরাসরি কুকিতে সংরক্ষণ করা বিপজ্জনক। আমরা এমন একটি পদ্ধতি উপস্থাপন করছি যা সার্ভারে মানগুলো সাইন করে ট্যাম্পারিং শনাক্ত করে। এখানে আমরা HMAC-SHA256 ব্যবহার করছি। প্রোডাকশন পরিবেশে সার্ভার-পক্ষে টোকেন বাতিলকরণও ব্যবস্থাপনা করতে হবে।
1// A simple HMAC signing and verification helper for cookies.
2// Signing prevents client from tampering cookie values.
3import crypto from 'crypto';
4
5const SECRET = 'replace_with_env_secret'; // store in env var in production
6
7const signValue = (value: string) => {
8 const hmac = crypto.createHmac('sha256', SECRET);
9 hmac.update(value);
10 return `${value}.${hmac.digest('hex')}`;
11};
12
13const verifySignedValue = (signed: string): string | null => {
14 const idx = signed.lastIndexOf('.');
15 if (idx === -1) return null;
16 const value = signed.slice(0, idx);
17 const sig = signed.slice(idx + 1);
18
19 const hmac = crypto.createHmac('sha256', SECRET);
20 hmac.update(value);
21 const expected = hmac.digest('hex');
22 // use timing-safe comparison in production
23 if (crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
24 return value;
25 }
26 return null;
27};
28
29// Example usage:
30const signed = signValue('userId=42');
31console.log('signed:', signed);
32console.log('verified:', verifySignedValue(signed)); // => "userId=42"
- এই পদ্ধতিতে আপনি কুকির মানটি কারসাজি করা হয়েছে কিনা পরীক্ষা করতে পারবেন। সাইনিং কী সোর্স কোডে অন্তর্ভুক্ত করবেন না; এনভায়রনমেন্ট ভেরিয়েবল ইত্যাদি নিরাপদ উপায়ে এটি পরিচালনা করুন।
কুকি ও CSRF প্রতিরোধ (সাধারণ প্যাটার্ন)
কুকি ব্যবহারকারী সেশনগুলোর CSRF সুরক্ষা প্রয়োজন। সাধারণ প্রতিরোধমূলক ব্যবস্থাগুলোর মধ্যে রয়েছে:।
- অনাবশ্যক ক্রস-সাইট পাঠানো ঠেকাতে
SameSite-কেLaxবাStrictদিন। ক্রস-অরিজিন যোগাযোগ প্রয়োজন হলে তবেইSameSite=None; Secureব্যবহার করুন। - ফর্ম ও API অনুরোধের জন্য সার্ভার দ্বারা যাচাইকৃত CSRF টোকেন ব্যবহার করুন। টোকেনকে
HttpOnlyকুকিতে সংরক্ষণ করবেন না; বরং রেসপন্স বডি বা মেটা ট্যাগের মাধ্যমে এটি প্রদান করুন, এবং প্রয়োজন হলে তবেই জাভাস্ক্রিপ্টকে এটি পড়তে দিন। - যদি টোকেনটি জাভাস্ক্রিপ্ট থেকে অ্যাক্সেস করা যায়, তবে অবশ্যই XSS সুরক্ষা (CSP, আউটপুট এস্কেপিং, ইত্যাদি) বাস্তবায়ন করুন।
- সংবেদনশীল কাজ ও লগইনের সময় পুনরায় প্রমাণীকরণ আবশ্যক করুন, এবং সেশন ফিক্সেশন আক্রমণ প্রতিরোধ করুন।
নিচে একটি নিরাপদ ক্লায়েন্টের উদাহরণ দেওয়া হলো, যা হেডারে CSRF টোকেন পাঠায়। এতে ধরা হচ্ছে যে ক্লায়েন্টটি সার্ভার থেকে আগেই টোকেনটি পেয়েছে, যেমন রেসপন্স বডিতে।
1// Example of sending CSRF token safely in a header using fetch.
2// Assumes CSRF token was provided securely (e.g., via response body or meta tag).
3async function sendProtectedRequest(url: string, csrfToken: string) {
4 const res = await fetch(url, {
5 method: 'POST',
6 credentials: 'same-origin', // include cookies for same-site requests
7 headers: {
8 'Content-Type': 'application/json',
9 'X-CSRF-Token': csrfToken
10 },
11 body: JSON.stringify({ action: 'doSomething' })
12 });
13 return res;
14}- আপনি যদি
credentials: 'same-origin'নির্দিষ্ট করেন, তবে কেবল একই অরিজিনের জন্য কুকি পাঠানো হয়। সার্ভারেX-CSRF-Tokenহেডারের মান যাচাই করুন এবং টোকেনটি মিলছে কিনা নিশ্চিত করুন। ক্রস-সাইট অনুরোধ প্রয়োজন হলে, CORS সতর্কতার সাথে কনফিগার করুন।
ক্রস-সাইট (CORS) এবং credentials-এর সম্পর্ক
ক্রস-অরিজিন যোগাযোগে কুকি পাঠাতে ও গ্রহণ করতে, ক্লায়েন্টকে credentials: 'include' নির্দিষ্ট করতে হবে এবং সার্ভারকে Access-Control-Allow-Credentials: true সেট করতে হবে। তবে, এই কনফিগারেশনটি কেবল বিশ্বস্ত অরিজিনগুলোর জন্য সীমাবদ্ধ করুন এবং Access-Control-Allow-Origin: * ব্যবহার করবেন না।
1async function fetchCrossOriginData() {
2 // Example: cross-origin fetch sending cookies.
3 // Server must set Access-Control-Allow-Credentials: true
4 // and a specific trusted origin.
5 const res = await fetch('https://api.example.com/data', {
6 credentials: 'include', // send cookies only to trusted domains
7 method: 'GET'
8 });
9 return res;
10}- নিরাপত্তার দৃষ্টিকোণ থেকে CORS এবং কুকির সমন্বয় খুবই সংবেদনশীল। অনুমোদিত অরিজিনগুলি হোয়াইটলিস্ট দিয়ে কঠোরভাবে পরিচালনা করুন এবং অপ্রয়োজনীয় ক্রস-সাইট যোগাযোগ এড়িয়ে চলুন। এছাড়া,
SameSite=None; Secureব্যবহার করার সময়, ম্যান-ইন-দ্য-মিডল আক্রমণ রোধে HTTPS বাধ্যতামূলক করুন।
উদাহরণ: Express (TypeScript) দিয়ে সুরক্ষিত সেশন কুকির সেটিংস
প্রয়োগে, Express, cookie লাইব্রেরি, express-session ইত্যাদি ব্যবহার করুন। নিচে express ও cookie-parser ব্যবহার করে একটি সহজ উদাহরণ রয়েছে। ব্যবহারিকভাবে, secure-কে true দিন এবং secret পরিবেশ ভেরিয়েবলের মাধ্যমে ম্যানেজ করুন।
1// Express example using cookie-parser and setting a secure httpOnly cookie.
2// npm install express cookie-parser @types/express @types/cookie-parser
3import express from 'express';
4import cookieParser from 'cookie-parser';
5
6const app = express();
7app.use(cookieParser(process.env.COOKIE_SECRET));
8
9app.post('/login', (req, res) => {
10 // authenticate user (omitted)
11 const sessionId = 'generated-session-id';
12 res.cookie('sid', sessionId, {
13 httpOnly: true,
14 secure: true, // require HTTPS in production
15 sameSite: 'lax',
16 maxAge: 1000 * 60 * 60 // 1 hour
17 });
18 res.json({ ok: true });
19});
20
21app.listen(3000);cookieParser-এরsecretফিচার ব্যবহার করে সাইনড কুকির সাথে সহজে কাজ করা যায়। তবে বাস্তব অ্যাপ্লিকেশনে, নিরাপত্তা ও স্কেলেবিলিটির দৃষ্টিকোণ থেকে, ডাটা সরাসরি কুকিতে সংরক্ষণ করা উচিত নয়; তার বদলে পৃথক সেশন স্টোর ব্যবহার করুন।
কুকি প্রিফিক্স __Host- এবং __Secure-
কিছু প্রিফিক্সের জন্য ব্রাউজার বিশেষ নিয়ম প্রয়োগ করে।
__Secure-প্রিফিক্স কুকির নাম__Secure-দিয়ে শুরু হলেSecureঅ্যাট্রিবিউট আবশ্যক।__Host-প্রিফিক্স এটি যদি__Host-দিয়ে শুরু হয়, তবেSecureআবশ্যক, path অবশ্যই/(root) হতে হবে, এবংDomainসেট করা যাবে না।
এগুলো ব্যবহার করলে ভুল কনফিগারেশন কমে ও নিরাপত্তা বাড়ে।
কুকি ব্যবহারের সেরা চর্চা
কুকি নিরাপদভাবে পরিচালনা করতে, নিম্নলিখিত বিষয়গুলো বিবেচনা করুন।
- সংবেদনশীল তথ্য সরাসরি কুকিতে সংরক্ষণ করবেন না। অ্যাক্সেস টোকেনের জন্য সার্ভার-সাইড সেশন আইডি প্রাধান্য দিন।
HttpOnly,Secure, এবংSameSite=Lax(বা Strict) সহ সেশন কুকি সেট করুন।__Host-ও__Secure--এর মতো প্রিফিক্স কাজে লাগান।- ট্যাম্পারিং ও গুপ্তশোনারোধে সিগনেচার (HMAC) ও এনক্রিপশন বিবেচনা করুন।
Secureসক্রিয় করুন এবং HTTPS আবশ্যক করুন।- সর্বনিম্ন অধিকার ও স্বল্প মেয়াদের দিকে লক্ষ্য রাখুন।
- CSRF টোকেন ব্যবহার করুন।
- বিভিন্ন ব্রাউজারে
SameSiteআচরণের পার্থক্য সম্পর্কে সতর্ক থাকুন, বিশেষ করে পুরনো ব্রাউজারগুলোতে।
কুকি সম্পর্কে সাধারণ ভুল ধারণা
কুকি সম্পর্কে নিচের সাধারণ ভুল ধারণাগুলোর বিষয়ে সচেতন থাকুন।
- '
HttpOnlyযোগ করলে XSS-এর প্রভাব দূর হয়।'HttpOnlyকুকিকে JavaScript থেকে অ্যাক্সেস করা রোধ করলেও, XSS ব্যবহার করে এখনও ইচ্ছামতো অনুরোধ পাঠানো যেতে পারে। CSRF টোকেন যাচাই, CSP (Content Security Policy), এবং ইনপুট স্যানিটাইজেশনও প্রয়োগ করা উচিত। - 'লোকাল ডেভেলপমেন্টে
Secureঅপ্রয়োজনীয়।' লোকাল পরিবেশেও HTTPS সিমুলেট করে এবং আচরণ যাচাই করে দেখলে টেস্টের নির্ভুলতা বাড়ে। কমপক্ষে, স্টেজিং ও প্রোডাকশন পরিবেশে HTTPS ব্যবহার করা উচিত। - 'দীর্ঘ মেয়াদের এক্সপায়ারি সুবিধাজনক।' কুকির মেয়াদ খুব দীর্ঘ করলে, সেগুলো চুরি হলে অপব্যবহারের সম্ভাব্য সময়ও বেড়ে যায়। আপনি কম মেয়াদের এক্সপায়ারি সেট করতে পারেন এবং নির্দিষ্ট সময় পরপর পুনরায় প্রমাণীকরণ (re-authentication) ও টোকেন রোটেশন যুক্ত করতে পারেন।
সারসংক্ষেপ
কুকি ব্যবহার করা সহজ হলেও, ভুল ব্যবহারে নিরাপত্তা দুর্বলতা তৈরি হতে পারে। TypeScript দিয়ে সঠিকভাবে ম্যানেজ করতে HttpOnly, Secure, এবং SameSite-এর মতো অ্যাট্রিবিউট বোঝা এবং সুরক্ষিত সার্ভার-সাইড সেটিংস প্রয়োগ করা গুরুত্বপূর্ণ। সংবেদনশীল ডেটা সরাসরি না রেখে এবং সিগনেচারকে স্বল্প মেয়াদের সঙ্গে মিলিয়ে আপনি নিরাপদ ও নির্ভরযোগ্য সেশন ম্যানেজমেন্ট নিশ্চিত করতে পারেন।
আপনি আমাদের ইউটিউব চ্যানেলে ভিজ্যুয়াল স্টুডিও কোড ব্যবহার করে উপরের নিবন্ধটি অনুসরণ করতে পারেন। দয়া করে ইউটিউব চ্যানেলটিও দেখুন।