နားလည်ထားရမယ့် အချက်
ဒီ project က cookies-and-sessions lesson နဲ့ authentication-versus-authorization lesson ကို ပေါင်းစပ်ထားပါတယ်။ Simulation က in-memory ပဲရှိပြီး real login system template မဟုတ်ပါ — password-security lesson အတိုင်း bcrypt/Argon2 ဒါမှမဟုတ် Auth0/Clerk ကို တကယ့် project မှာ သုံးပါ။
HTTP က stateless ဖြစ်လို့ login ပြီးနောက် server က session record ဖန်တီးပြီး session ID ပါတဲ့ cookie ကို browser ကို ပေးပါတယ်၊ browser က နောက် request တိုင်း auto-attach လုပ်ပါတယ်။
| Concept | ဖြေတဲ့မေးခွန်း |
|---|---|
| Authentication | ဒါက ဘယ်သူလဲ — login မှာ တစ်ကြိမ်ဖြစ်ပြီး session lookup အောင်မြင်တိုင်း ထပ်ဖြစ်ပါတယ် |
| Authorization | ဒီ user ဒီအလုပ်ကို လုပ်ခွင့်ရှိလား — request/action တိုင်းအလိုက် ခွဲပြီး စစ်ပါတယ် |
Production auth template မဟုတ်ပါ
ဒီ code က concept ကို ပြသဖို့ သာဖြစ်ပြီး password hashing၊ cookie security flags (HttpOnly, Secure, SameSite)၊ session expiry တို့ ချန်ထားခဲ့ပါတယ် — real system အတွက် established library/provider ကို သုံးပါ။
Request နှစ်ခုကို ဘေးချင်းယှဉ်ကြည့်တာကပဲ အဓိကအချက်ဖြစ်ပါတယ် — admin action က session/cookie ပျက်နေလို့ မဟုတ်ဘဲ authorization rule ကြောင့် fail ဖြစ်တာ ဖြစ်ပါတယ်။
AUTHENTICATION VS AUTHORIZATION FLOW
------------------------------------
AUTH FLOW: LOGIN -> SESSION -> COOKIE -> AUTHORIZATION CHECK
----------------------------------------------------------------
[User] --1. login(username, password)--> [Backend]
|
2. verify credentials
|
3. create session record
(id -> user, role)
|
4. Set-Cookie: session_id=X
v
[Browser stores cookie]
|
(cookie is attached automatically to later requests)
v
[Request N] --Cookie: session_id=X--> [Backend]
|
5. session lookup (authN)
|
6. authorization check (authZ)
|
+------------------+------------------+
| |
allowed denied
v v
200 OK response 403 Forbiddenလက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
Run မခင် code ကို ဖတ်ပြီး output ကို ခန့်မှန်းကြည့်ပါ — alice (user) နဲ့ bob (admin) နှစ်ယောက်လုံး login ဝင်ပြီးနောက် 'delete-user' action ကို ကြိုးစားကြည့်ပါတယ်။
Alice login ဝင်ပါတယ်
Backend က password ကို စစ်ပြီး session record ဖန်တီးကာ session_id ပါတဲ့ cookie-like string ကို ပြန်ပေးပါတယ်။
Request 1: view-dashboard
Alice ရဲ့ cookie နဲ့ request တင်လိုက်တဲ့အခါ session lookup အောင်မြင်ပြီး action ကို ခွင့်ပြုပါတယ်။
Request 2: delete-user (denied)
Alice ဆက်ပြီး authenticated ဖြစ်နေပေမယ့် role က 'user' ဖြစ်လို့ authorization check က 403 ဖြင့် ငြင်းပယ်ပါတယ်။
Bob login ဝင်ပါတယ်
Role 'admin' ရှိတဲ့ Bob အတွက် session အသစ်တစ်ခု ဖန်တီးပြီး session ID အသစ်တစ်ခု ပြန်ပေးပါတယ်။
Request 3: delete-user (allowed)
Bob ရဲ့ session က authentication နဲ့ authorization check နှစ်ခုစလုံးကို pass ပြီး action ခွင့်ပြုခံရပါတယ်။
Code ကို run ပြီးရင် bob ရဲ့ role ကို 'user' အဖြစ် ပြောင်းပြီး ပြန် run ကြည့်ပါ — denial logic မှန်ကန်စွာ တုံ့ပြန်လားဆိုတာ အတည်ပြုပါ။
အတူတူ စမ်းရေးကြည့်မယ်
// Mock user 'database'. In a real system, passwords are never stored or
// compared in plaintext -- see the password-security lesson and use an
// established library (bcrypt, Argon2) or an auth provider (Auth0, Clerk).
const users = {
alice: { password: 'hunter2', role: 'user' },
bob: { password: 'adminpass', role: 'admin' },
};
// In-memory session store: sessionId -> { username, role }
const sessions = {};
let sessionCounter = 0;
function createSessionId() {
sessionCounter += 1;
return `sess_${sessionCounter}`;
}
function login(username, password) {
const user = users[username];
if (!user || user.password !== password) {
return { ok: false, reason: 'invalid credentials' };
}
const sessionId = createSessionId();
sessions[sessionId] = { username, role: user.role };
return { ok: true, cookie: `session_id=${sessionId}` };
}
function request(cookie, action) {
const sessionId = cookie.split('=')[1];
const session = sessions[sessionId];
if (!session) {
return { status: 401, body: 'not authenticated' };
}
// Authentication (who are you) already passed. This is authorization
// (are you allowed to do THIS specific thing).
if (action === 'view-dashboard') {
return { status: 200, body: `${session.username} viewed the dashboard` };
}
if (action === 'delete-user') {
if (session.role !== 'admin') {
return {
status: 403,
body: `${session.username} is authenticated but NOT authorized (needs admin)`,
};
}
return { status: 200, body: `${session.username} deleted a user` };
}
return { status: 404, body: 'unknown action' };
}
const aliceLogin = login('alice', 'hunter2');
console.log('Login (alice):', aliceLogin);
console.log('Request 1 (view-dashboard):', request(aliceLogin.cookie, 'view-dashboard'));
console.log('Request 2 (delete-user): ', request(aliceLogin.cookie, 'delete-user'));
const bobLogin = login('bob', 'adminpass');
console.log('Login (bob): ', bobLogin);
console.log('Request 3 (delete-user): ', request(bobLogin.cookie, 'delete-user'));Code ကို run လိုက်ရင် authentication success (login/view-dashboard) နဲ့ authorization denial (delete-user) ကို ရှင်းရှင်းလင်းလင်း မြင်ရပါတယ်:
Login (alice): { ok: true, cookie: 'session_id=sess_1' }
Request 1 (view-dashboard): { status: 200, body: 'alice viewed the dashboard' }
Request 2 (delete-user): { status: 403, body: 'alice is authenticated but NOT authorized (needs admin)' }
Login (bob): { ok: true, cookie: 'session_id=sess_2' }
Request 3 (delete-user): { status: 200, body: 'bob deleted a user' }၅ မိနစ် စမ်းကြည့်
role 'moderator' ရှိတဲ့ user တတိယယောက်ကို ထည့်ပါ — view-dashboard နဲ့ 'edit-post' action အသစ်ကို ခွင့်ပြုပေမယ့် delete-user ကိုတော့ ခွင့်မပြုစေချင်ပါ။ authentication နဲ့ authorization ကို ဆက်လက်သီးခြားစစ်ဆေးနေကြောင်း သက်သေပြပါ။
သတိလေးတစ်ချက်
Session ID ကို predictable pattern (sess_1, sess_2...) နဲ့ ဒီအတိုင်း production မှာ သုံးခြင်း — real session ID တွေဟာ cryptographically random ဖြစ်ရပါမယ်
403 (authorization denial) ကို 401 (not authenticated) နဲ့ ရောထွေးပြီး error message တစ်ခုတည်းအဖြစ် ကိုင်တွယ်ခြင်း
OWASP Session Management Cheat Sheet — How the Web Works