Cookies and Sessions: জানেন তো কী জিনিস?
কুকি এবং সেশন- আসলে কি জিনিস বা কি কাজে লাগে? অনেকেই হয়তো হাল্কার উপর ঝাপসা ধারণা রাখেন, কেউ কেউ হয়তো ওয়েব ডেভেলপমেন্টে কাজ করতে গিয়ে শিখেছেন সার্ভার সাইডের কোডের শুরুতে ‘সেশন’ শুরু করতে হয় আর সেশন ভ্যারিয়েবলে কিছু ডাটা সেভ করে রাখা যায়- ব্যস এতটুকুই। প্রোগ্রামিং ল্যাঙ্গুয়েজের সিন্ট্যাক্স দিয়ে ঠিক যতটুকু কাজ করতে লাগে ততটুকুই শিখেছেন অথচ পুরোপুরি ক্লিয়ার কোনো ধারণা রাখেন না। তাঁদের জন্যই আজকের এই লেখা। কুকি এবং সেশন ওয়েব ডেভেলপমেন্টের কাজ করার জন্য একেবারেই প্রাথমিক একটা কন্সেপ্ট যেটা ভালোমতো জানা থাকা খুবই জরুরী। কথা না বাড়াই, চলুন মূল আলোচনা শুরু করি।
কুকি (Cookie) কী?
এ ধরণের পপ-আপ আমরা প্রায়ই দেখে থাকি। যেখানে বলা থাকে যে “এই সাইটটি কুকি ব্যবহার করছে, যাতে করে এই সাইটটি ব্যবহারের আপনার এক্সপেরিয়েন্স আরো ভালো হয়।” বা এ জাতীয় কিছু একটা। কিন্তু কী এই কুকি? কী কাজে লাগে? এভাবে পার্মিশনই বা নেয় কেন সাইটগুলো? পিএইচপি, পাইথন, জাভাস্ক্রিপ্ট ব্যবহার করার সময় তো পার্মিশন নেয় না। তাহলে কুকির বেলায় কেন?
আমরা যখন কোনো একটা ওয়েবসাইট বা ওয়েব এপ্লিকেশন ব্যবহার করি তখন আমরা (মূলত আমাদের ওয়েব ব্রাউজার) হচ্ছি ক্লায়েন্ট, যে কিনা দূরবর্তী কোনো একটা সার্ভারের কাছে রিকোয়েস্ট করে কোনো একটা কন্টেন্ট এর জন্য। আর সার্ভার যদি অচল না থাকে বা অন্য কোনো প্রবলেম না হয় তাহলে সার্ভারটি সফলভাবে সেই কন্টেন্টটি রেসপন্স হিসেবে ক্লায়েন্টের কাছে, মানে আমাদের কাছে ফেরত পাঠায়। এই ধরনের রিকোয়েস্ট-রেসপন্স এর উপর ভিত্তি করেই মূলত পুরো ইন্টারনেট ব্যবস্থা চালু আছে। এখন এই যে, রিকোয়েস্ট আর রেসপন্স চালাচালি হয় এটার জন্য যেই প্রটোকল বা কমিউনিকেশন মেথড(HTTP) ব্যবহার হয় সেটা আসলে Stateless. এর মানে কি? এর মানে হলো একটা রিকোয়েস্ট-রেসপন্স সম্পন্ন হয়ে গেলে ঠিক পরবর্তী রিকোয়েস্ট যদি একই ক্লায়েন্ট থেকেও আসে, সার্ভারের বোঝার কোনো উপায় নেই যে এটি ঠিক আগের ক্লায়েন্টের কাছ থেকেই এসেছে। এখানে প্রত্যেকটা রিকোয়েস্ট ও রেসপন্স জোড়া আলাদা। আগেরগুলোর সাথে কোন সম্পর্ক নেই। সার্ভার আপনার রিকোয়েস্টের স্টেট বা অবস্থা মনে রাখে না। আপনি সার্ভারকে বলতে পারবেন না যে আগেরবার যে পেজটা ভিজিট করেছিলাম ঐটা দাও। প্রতিবার রিকোয়েস্টে আপনাকে নির্দিষ্ট করে বলতে হবে যে আমার এই URL এর পেজটা চাই।
এখন আপনি নিশ্চয়ই ভাবছেন যে, আমরা যখন প্রথমবার facebook.com URL এর পেজটার জন্য রিকোয়েস্ট পাঠাই, ফেসবুকের সার্ভার তখন আমাদের একটা লগিন পেজ দেয়। সেখানে ইউজার নেম, পাসওয়ার্ড দেয়ার পরে ফেসবুক আমাদের নিজেদের নিউজ ফিড বা হোম পেজ দেয়। পরে যদি ঐ একই ব্রাউজার থেকে facebook.com URL এর জন্য রিকোয়েস্ট পাঠাই তখন কিন্তু সরাসরি আমাদের হোমপেজ দিয়ে দেয়। HTTP যদি স্টেটলেস প্রটোকল হয়, তাহলে তাহলে তো আমাকে মনে রাখার কথা না। এটা কিভাবে সম্ভব হয়?
আসলে আমরা যখন ফেসবুকে ব্রাউজারের মাধ্যমে ইউজারনেম, পাসওয়ার্ড সাবমিট করি, ফেসবুক তখন আমাদের হোম পেজের পাশাপাশি আরেকটা ছোট ইনফরমেশন বা টেক্সট ব্রাউজারে পাঠিয়ে দেয় (টেকনিক্যালি বলতে গেলে সার্ভারের রেসপন্সে HTTP Header এ Set-Cookie হিসেবে এই ডাটাটা আসে)। ব্রাউজার সেটা আমাদের না দেখিয়ে সেভ করে রাখে। তারপরে যতবার আমরা ঐ ব্রাউজার দিয়ে ফেসবুকে রিকোয়েস্ট পাঠাই, ব্রাউজার সেই সেভ করে রাখা ইনফরমেশন বা টেক্সট রিকোয়েস্টের সাথে ফেসবুকের সার্ভারে পাঠায় (আবারো একটু টেকনিক্যালি বলি, ক্লায়েন্ট থেকে পরবর্তী রিকোয়েস্টগুলোতে HTTP Header এ Cookie নামে এই ডাটাটা সার্ভারের কাছে যায়)। সার্ভার তখন সেই টেক্সট বা ইনফরমেশন দেখে বুঝতে পারে এটা কোন ইউজারের কাছ থেকে এসেছে এবং কার হোমপেজ পাঠাতে হবে। এই ব্রাউজারে বা ক্লায়েন্ট সাইডে যে ছোট ইনফরমেশন বা টেক্সট সেভ করে রাখা হয় তাই হল কুকি। কুকি আসলে অত জটিল কোনো কিছু না, জাস্ট key-value হিসেবে কিছু ডাটা সেভ করে রাখে, এই যা। আর কুকি কীভাবে ম্যানেজ করতে হবে, মানে কখন কীভাবে সেট করতে হবে, আবার কখন কীভাবে পাঠাতে হবে এগুলো ব্রাউজারের কাজ, আমাদের আপাতত না জানলেও চলবে।
কুকিতে মূলত সাইটগুলো তাঁদের ইউজারের সেশন(Session) ইনফরমেশন রাখে (সেশন নিয়ে বিস্তারিত সামনে আসছে, পড়তে থাকুন)। তা না হলে প্রতিবার ফেসবুকের পেজ রিফ্রেশ দিলে বা কোনো একটা বাটনে ক্লিক করে অন্য কোনো পেজে যেতে চাইলে ইউজার নেম, পাসওয়ার্ড দিয়ে লগিন করা লাগতো, কারণ তা না হলে ফেসবুকের সার্ভার তো বুঝতেই পারতো না কোন ক্লায়েন্ট এই নতুন পেজের জন্য রিকোয়েস্টটা করেছে। এছাড়াও কুকির মাধ্যমে সাইটগুলো তাদের সুবিধামত ক্লায়েন্ট সাইডে অনেক ইনফরমেশনই রাখে। চাইলে এখনি দেখতে পারেন। ফায়ারফক্সে F12 প্রেস করে DevTool খুলুন। তারপর Storage ট্যাবে ক্লিক করুন। ডানপাশে Cookies ক্লিক করে ফেসবুক সিলেক্ট করুন। যেমন আমি দেখতে পাচ্ছি ফেসবুক আমার ব্রাউজারে বেশ কিছু ভ্যারিয়েবলে ইনফরমেশন সেভ করে রেখেছে। এখানে বেশিরভাগ ডেটা দেখে কিছুই বুঝা যায় না। তবে দুই একটা বুঝা যায়। যেমন c_user সম্ভবত ইউজার আইডি রেখেছে। locale রেখেছে en_US, ভাষা সেটিং।
ক্রোমেও একইভাবে দেখা যাওয়ার কথা।
কুকি ব্যবহার করে শুধু লগিন ইনফরমেশন ছাড়াও অনেক কিছু রাখা যায়। যেমন আপনি একটা শপিং সাইটে গিয়ে কিছু প্রোডাক্ট ব্রাউজ করলেন। সেই সাইট কুকির মাধ্যমে রেখে দিল আপনি কি কি প্রোডাক্ট ব্রাউজ করলেন। পরের বার যখন আপনি ঐ সাইট ব্রাউজ করবেন তখন আপনাকে ঐ প্রোডাক্টের সাথে রিলেটেড প্রোডাক্ট দেখাবে।এমনকি দেখা গেলো আপনি প্রোডাক্ট কার্টে এড করে রেখে দিলেন চেকআউট করলেন না, এমন অবস্থায় ব্রাউজার বন্ধ করে দিয়ে পরেরবার যখন আবার ব্রাউজার ওপেন করে ঐ সাইটে গেলেন, দেখলেন যে আপনার ঐ প্রোডাক্টগুলো ঠিকই কার্টে রয়ে গেছে। এটা মূলত কুকি দিয়েই করে, আপনার কার্টে এড করা প্রোডাক্ট ইনফরমেশনগুলো কুকিতে সেভ করে রেখে দিয়েছে ওরা। মজা না?
গুগলের এডসেন্স বা এই ধরণের সার্ভিসগুলোও কুকি ব্যবহার করেই কাজ করে। এডসেন্সওয়ালা সাইটগুলোর পেইজে গুগলের কিছু কোড এমবেডেড থাকে। সেই কোডগুলো ব্রাউজারের কুকি দেখে আপনাকে চিনতে পারে ও আপনার আগে ব্রাউজ করা সাইট বা সার্চ ইন্টারেস্ট অনুসারে রিলেটেড এড দেখায়। আমি একবার কিছু একটা গুগলে সার্চ করে কয়েকটা পেজ ভিজিট করেছিলাম। তারপরে মোবাইলে ফেসবুক খুলে ঠিক সেই প্রোডাক্টের এড দেখে চমকে উঠেছিলাম। কারণ ফেসবুকে আমি কখনোই ঐ প্রোডাক্ট খুঁজি নাই বা রিলেটেড কিছুতে লাইক দেই নাই। মনে হচ্ছিল ফেসবুক বুঝি আমার সকল ব্রাউজিং হিস্ট্রি চেক করছে। আসলে ঐ সাইটে ফেসবুকের থার্ড পার্টি কুকি ছিল।
কুকি ব্যবহার করে ইউজারের অনেক এক্টিভিটিই ট্র্যাক করা যায়। যা প্রাইভেসির ভায়োলেশন হতে পারে। তাই ইউরোপীয় ইউনিয়নের আইন অনুযায়ী যদি কোন সাইট কুকি ব্যবহার করে তাহলে অবশ্যই ইউজার থেকে পার্মিশন নিতে হবে। আমরা যেসব সাইটে একদম প্রথমে দেখানো পপ-আপের মত পপ-আপ দেখি সেটা মূলত এই আইন মান্য করার কারণেই করা হয়।
কুকি নিয়ে আর ছোট্ট একটা ইনফরমেশন দিয়ে কুকি নিয়ে বকর বকর শেষ করবো। কিছু কুকি আছে যেগুলো খুব অল্প সময়ের জন্য সেভ থাকে। যেমন আপনি ব্রাউজার ক্লোজ করে দিলেই ঐ কুকিগুলো রিমুভ হয়ে যাবে। এই কুকিগুলোকে বলে ‘সেশন কুকি(Session Cookie)’। সেশন কুকি এর জন্য সার্ভার কোনো এক্সপায়ারেশন ডেট বলে দেয় না। একারণে এই কুকিগুলোকে ব্রাউজার পারমানেন্টলি স্টোর করে না, জাস্ট মেমরিতে রেখে দেয়।
যে কুকিগুলোর জন্য ব্রাউজার এক্সপায়ারেশন ডেট বলে দেয় সেগুলোকে ব্রাউজার পারমানেন্টলি ডিস্কে সেভ করে রাখে এবং ব্রাউজার বা কম্পিউটার বন্ধ করলেও এই কুকিগুলো রিমুভ হয় না যতক্ষণ না সেগুলোর এক্সপায়ারেশন ডেট ওভার হয়ে যায় কিংবা আপনি ব্রাউজারের সেটিংস থেকে সেগুলোকে রিমুভ করে করে দেন। এ ধরনের কুকিগুলোকে বলা হয় ‘পারসিস্টেন্ট কুকি (Persistent Cookie)’।
সেশন
আগেই বলেছি, HTTP স্টেটলেস হওয়ার কারণে কুকিতে ইউজারের কিছু ডাটা রেখে দেয়া হয় যাতে করে পরবর্তী রিকোয়েস্টে সেই ইউজারকে চেনা যায়। এখন ইউজারের গুরুত্বপূর্ণ ডাটা যদি সব কুকিতে রেখে দেয়া হয় তাহলে সেটা একটু ইন্সিকিউর, তাই না? রাখা সম্ভব যদিও, কিন্তু উচিত না। তাহলে উপায় কি?একটা কাজ করা যায় যে ক্লায়েন্ট সাইডে ইউজারের ডাটাগুলো এনক্রিপ্ট করে রেখে দেয়া এবং এনক্রিপশন কী টা সার্ভার সাইডে রেখে দেয়া। এটা ‘ক্লায়েন্ট সাইড সেশন’ হিসেবে পরিচিত।
আরেকটা উপায় যেটা বহুল ব্যবহৃত এবং মোটামুটি স্ট্যান্ডার্ড প্র্যাক্টিস তা হচ্ছে ইউজারকে চেনার জন্য যেই ইনফরমেশনগুলো দরকার (যেমন ডাটাবেজে ঐ ইউজারের আইডি, নাম বা এরকম কিছু) সেগুলো সার্ভার সাইডেই সেভ করে রেখে ক্লায়েন্টকে শুধু সেটার একটা ইউনিক আইডি দিয়ে দেয়া, যাতে করে পরবর্তীতে ক্লায়েন্ট থেকে ঐ আইডিটা পাঠালেই তার ইনফরমেশনগুলো বের করে নেয়া যায়। এই আইডিটাকে বলা হয় ‘সেশন আইডি’। সার্ভার সাইডে ফাইলে, ডাটাবেইজে বা ইন-মেমোরী ক্যাশে এই সেশন আইডি এবং তাঁর সাথে ইউজারের ডেটা রাখা হয়। প্রথমবার ইউজার যখন সফলভাবে কোনো সাইটে লগিন করে তখনই তাঁর জন্য এই সেশন আইডিটা তৈরি করে সেটা স্টোর করে রাখা হয় এবং সেটা ক্লায়েন্ট সাইডে পাঠিয়ে দেয়া হয়। পরবর্তী রিকোয়েস্ট গুলোতে ক্লায়েন্ট এই সেশন আইডিটা পাঠায়। তখন সার্ভার এই সেশন আইডি ম্যাচ করে স্টোর করা ইনফরমেশন দেখে চেনে এটা কোন ক্লায়েন্ট এবং সে authenticated কিনা। এটা ‘সার্ভার সাইড সেশন’ নামে পরিচিত।
আগেই বলে এসেছি, এই সেশন ডাটা ক্লায়েন্ট সাইডে ‘সেশন কুকি’ হিসেবে সেইভ থাকে এবং ব্রাউজার বন্ধ করলে এই সেশন কুকি রিমুভ হয়ে যায়। একারণেই আপনি ব্রাউজার বন্ধ করে আবার ওপেন করলে যেসব সাইটে লগিন করা ছিলেন সেগুলোতে আবার নতুন করে লগিন করতে হয়, কারণ আপনার সেশনটি আর এক্টিভ থাকে না। যতক্ষণ একজন ইউজার একটা সাইটে এক্টিভ থাকে এবং তাঁর সেশন ডাটা কুকিতে সেইভ থাকে সেটাই তার একটা ‘সেশন’।
সার্ভার সাইড না ক্লায়েন্ট সাইড?
দুটি পদ্ধতিরই বেশ কিছু সুবিধা অসুবিধা আছে। ক্লায়েন্ট সাইডে রাখার একটি সুবিধা হল স্পিড। ডেটাবেজ চেক করতে হয় না বলে অনেক দ্রুত প্রসেস করা যায়। সার্ভার সাইডেও ইন মেমরি ক্যাশ ব্যবহার করে ব্যবস্থাটি ফাস্ট করে তোলা যায়। সেক্ষেত্রে আবার সার্ভারে অনেক বেশি মেমরি দরকার। বিশেষ করে যদি সাইটটির বিশাল সংখ্যক ইউজার থাকে।
আবার বড় বড় সাইটের একাধিক সার্ভার নোড বা সার্ভার ইন্সট্যান্স থাকে এবং কোন রিকোয়েস্ট কোন সার্ভারে যাবে সেটা ম্যানেজ করার জন্য লোড ব্যালেন্সার(Load Balancer) থাকে। দেখা যায় একটা সেশনের একেকটি রিকোয়েস্ট একেকটি নোড প্রসেস করছে। সার্ভার সাইডে সেশন রাখলে প্রত্যেকটি নোড নতুন সেশন তৈরী করে ফেলে এবং তাতে সেশন ব্যবহারের উদ্দেশ্যই ব্যাহত হয়। কারণ প্রথম রিকোয়েস্টটি যদি Node-A তে যায় তাহলে সেখানে ঐ ইউজারের জন্য একটা সেশন তৈরি হবে, কিন্তু পরবর্তী রিকোয়েস্টটি যদি Node-B তে যায়, তাহলে সেখানে কিন্তু এই ইউজারের কোনো সেশন তৈরি হয়নি তাই ইউজারকে unauthenticated দেখাবে এবং আবার লগিন করতে বলবে। এটা একটা বিরাট সমস্যা, তাই না? এই সমস্যা সমাধানের জন্য স্টিকি সেশন (Sticky Session) ব্যবহার করা হয়। এতে করে লোড ব্যালেন্সার একটি সেশনের জন্য একটি নোড ঠিক করে দেয়। ঐ সেশনের সকল রিকোয়েস্ট সেই নোড প্রসেস করে। ক্লায়েন্ট সাইড সেশন ব্যবহার করলে সেই সকল ঝামেলায় যেতেই হয় না।
ক্লায়েন্ট সাইড সেশনের একটি অসুবিধা হল সেশন ডেটাগুলো ক্লায়েন্ট সাইডে এক্সপোজড থাকে। ইউজার চাইলেই সেগুলো দেখতে পারে যা অনেক ক্ষেত্রে অবাঞ্ছিত। আবার সেগুলো ম্যালওয়্যার বা অন্য কোনভাবে ক্লায়েন্ট সাইড থেকে চুরি বা কম্প্রোমাইজও হয়ে যেতে পারে। এই সমস্যা সমাধানের জন্য ক্লায়েন্ট সাইডে ডেটাগুলো এনক্রিপ্ট করে রাখা যায়, যেটা আগেই বলেছি।
ক্লায়েন্ট সাইডের আরেকটি বড় অসুবিধা হল সাইজ। প্রতিটি সাইটের জন্য সাধারণত ৪ কেবি জায়গা বরাদ্দ থাকে। তাই বিশাল পরিমাণ ডেটা রাখতে চাইলে সার্ভার সাইডেই রাখতে হবে।
সেশন হাইজ্যাকিং (Session Hijacking)
সার্ভার সেশন কিংবা কুকিতে রাখা ডেটা দেখে আমাকে আইডেন্টিফাই করে ও আমার পার্সোনাল ডেটা সার্ভ করে। এখন ভাবুন তো যদি এই ডেটাগুলো বা সেশন আইডেন্টিফায়ার টোকেনটি অন্য কারো হাতে চলে যায় তাহলে কি হবে? সে এগুলো HTTP রিকোয়েস্টের সাথে পাঠাতে পারবে। আর সার্ভার তাকে ভুল করে আইডেনটিফাই করবে এবং আমার পার্সোনাল ডেটা দিয়ে দেবে। এই ধরণের অ্যাটাক সেশন হাইজ্যাকিং হিসেবে পরিচিত। এই ধরণের অ্যাটাক থেকে বাঁচতে হলে ফোনে বা পিসিতে কোন মেলিশিয়াস প্রোগ্রাম ইন্সটল করা যাবে না। কেননা এগুলো প্রায়ই কুকি চুরি করতে চেষ্টা করে। এন্টিভাইরাস ব্যবহার করা যেতে পারে।
সেশন হাইজ্যাকিং এড়াতে সার্ভার সাইডেও বিভিন্ন ব্যবস্থা নেয়া যায়। যেমন সেশন ডেটায় আইপি এড্রেস, ব্রাউজারের ধরণ ইত্যাদি রাখা যায়। পরে সেশন এগুলো মিলিয়ে দেখে সেশন আইডেন্টিফায়ার যাচাই করা যায়।
অনেক তো আলোচনা হলো, আশা করি এই বিষয়ের উপরে একেবারে এক্সপার্ট না হলেও কাজ করার মত পর্যাপ্ত ধারণা পেয়ে গেছেন। আপনার সাথে আমার সেশন এখানেই সমাপ্ত। আর এত বড় পোস্ট করে পড়ার জন্য আপনার জন্য এই সুস্বাদু কুকি। :D
এই আর্টিকেলটি যুগ্মভাবে লিখেছেন Ahmed shamim hassan ও S.j. Sakib