Session Based Authentication
Session-based authentication nima ekanini va uni Node.js'da qanday amalga oshirishni o'rganing
Muallif: Kamran Ahmed
HTTP — client'lar va server'lar bir-biri bilan qanday o'zaro ishlashini standartlashtiradigan internet protokoli. Veb-saytni ochganingizda, boshqa narsalar qatori, veb-saytni brauzerda yuklashga yordam beradigan protokol ham aynan HTTP'dir.
HTTP stateless
HTTP — stateless protokol, ya'ni client'dan serverga yuborilgan har bir so'rov alohida, mustaqil so'rov sifatida qaraladi; na client, na server keyingi so'rovlarni kuzatib boradi. Session'lar buni o'zgartirishga imkon beradi: session'lar yordamida server client bilan qandaydir ma'lumotni bog'lab qo'yish imkoniga ega bo'ladi, shunda o'sha client serverga yana so'rov yuborganda server bu ma'lumotni qayta olishi mumkin.
Ushbu qo'llanmada session-based authentication nima ekanini va uni Node.js'da qanday amalga oshirishni o'rganamiz. Shuningdek, bizda mavzuni vizual tarzda tushuntiradigan alohida session-based authentication bo'yicha vizual qo'llanma ham bor.
Session-based authentication nima?
Session-based authentication — authenticate qilingan foydalanuvchini kuzatib borish uchun session'lardan foydalanadigan stateful authentication usuli. Session-based authentication quyidagicha ishlaydi:
- Foydalanuvchi authentication uchun login so'rovini yuboradi.
- Server credential'larni tekshiradi. Agar credential'lar to'g'ri bo'lsa, server session boshlaydi va client haqida qandaydir ma'lumotni saqlaydi. Bu ma'lumot xotirada, fayl tizimida yoki ma'lumotlar bazasida saqlanishi mumkin. Server, shuningdek, keyinchalik bu session ma'lumotini storage'dan olish uchun ishlatishi mumkin bo'lgan noyob identifikator generatsiya qiladi. Server bu noyob session identifikatorini client'ga yuboradi.
- Client session id'ni cookie'da saqlaydi va bu cookie authentication'dan keyin yuboriladigan har bir so'rovda serverga jo'natiladi.
- Server so'rovni qabul qilganda, so'rovda session id bor-yo'qligini tekshiradi va client haqidagi ma'lumotni olish uchun shu session id'dan foydalanadi.
Session-based authentication mana shunday ishlaydi.
Node.js'da session-based authentication
Endi session-based authentication nima ekanini bilganimizdan so'ng, uni Node.js'da qanday amalga oshirish mumkinligini ko'rib chiqaylik.
E'tibor bering, soddalik uchun men loyihani ataylab faqat session-based authentication'ga tegishli qilib qoldirdim va production'ga tayyor ilova talab qilishi mumkin bo'lgan ko'plab tafsilotlarni tushirib qoldirdim. Shuningdek, agar qadamma-qadam bajarishni xohlamasangiz, loyihaning codebase'ini GitHub'da topishingiz mumkin.
Eng avvalo, ilovamiz joylashadigan bo'sh papka yarating.
mkdir session-auth-example
Endi namunaviy package.json faylini yaratish uchun quyidagi buyruqni bajaring:
npm init -y
Keyin dependency'larni o'rnatishimiz kerak:
npm install express express-session
Express — ilova freymvorki, express-session esa session'lar bilan oson ishlashga yordam beradigan package.
Serverni sozlash
Endi loyihaning root papkasida quyidagi tarkibga ega index.js faylini yarating:
const express = require('express');
const sessions = require('express-session');
const app = express();
app.use(
sessions({
secret: 'some secret',
cookie: {
maxAge: 1000 * 60 * 60 * 24, // 24 hours
},
resave: true,
saveUninitialized: false,
})
);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// @todo register routes
app.listen(3000, () => {
console.log(`Server Running at port 3000`);
});
Bu yerda e'tibor berish kerak bo'lgan muhim qism — express-session middleware'ining ro'yxatdan o'tkazilishi. U session'ni ishga tushirish, cookie'ni parse qilish, session ma'lumotlarini olish va hokazolarni avtomatik bajaradi. Bizning misolimizda quyidagi konfiguratsiya parametrlarini uzatyapmiz:
secret: Session ID cookie'sini imzolash uchun ishlatiladi. Taxmin qilib bo'lmaydigan secret'dan foydalanish session'ni hijack qilish imkoniyatini kamaytiradi.cookie: Session id cookie'si uchun konfiguratsiyani o'z ichiga olgan obyekt.resave: So'rov davomida session ma'lumotlari umuman o'zgartirilmagan bo'lsa ham, session'ni session store'ga qayta saqlashga majbur qiladi.saveUninitialized: "Initialize qilinmagan" session'ni store'ga saqlashga majbur qiladi, ya'ni session boshlanmagan bo'lsa ham uni store'ga saqlaydi.
Yana bir muhim parametr — store. Uni sozlab, session ma'lumotlari serverda qanday/qayerda saqlanishini o'zgartirishimiz mumkin. Default holatda bu ma'lumotlar xotirada, ya'ni MemoryStore'da saqlanadi.
Mavjud parametrlar haqida ko'proq bilish uchun express-session hujjatlarini ko'rib chiqing.
Handler'larni yaratish
Loyihaning root papkasida handlers nomli papka yarating. Barcha route'larni qayta ishlovchi funksiyalarni shu papkaga joylashtiramiz.
Endi bosh sahifa route'ini yarataylik: u login qilgan foydalanuvchilarga xush kelibsiz xabari va logout havolasini ko'rsatadi, login qilmagan foydalanuvchilarni esa login ekraniga redirect qiladi. Quyidagi tarkibga ega handlers/home.js faylini yarating.
module.exports = function HomeHandler(req, res) {
if (!req.session.userid) {
return res.redirect('/login');
}
res.setHeader('Content-Type', 'text/HTML');
res.write(`
<h1>Welcome back ${req.session.userid}</h1>
<a href="/logout">Logout</a>
`);
res.end();
};
Bu funksiyaning boshida req.session.userid tekshiruvini ko'rasiz. req.session biz avvalroq ro'yxatdan o'tkazgan express-session middleware tomonidan session cookie'si asosida avtomatik to'ldiriladi. req.session.userid — login qilgan foydalanuvchining userid'sini saqlash uchun biz o'rnatadigan ma'lumot maydonlaridan biri.
Keyin bu handler'ni route bilan ro'yxatdan o'tkazishimiz kerak. Loyihaning root papkasidagi index.js faylini oching va quyidagi route'ni ro'yxatdan o'tkazing:
const HomeHandler = require('./handlers/home.js');
app.get('/', HomeHandler);
Keyingisi — login sahifasi: agar foydalanuvchi login qilgan bo'lsa, u foydalanuvchini bosh ekranga redirect qiladi, aks holda login formasini ko'rsatadi. Quyidagi tarkibga ega handlers/login.js faylini yarating:
module.exports = function LoginHandler(req, res) {
if (req.session.userid) {
return res.redirect('/');
}
res.setHeader('Content-Type', 'text/HTML');
res.write(`
<h1>Login</h1>
<form method="post" action="/process-login">
<input type="text" name="username" placeholder="Username" /> <br>
<input type="password" name="password" placeholder="Password" /> <br>
<button type="submit">Login</button>
</form>
`);
res.end();
};
Yana funksiyaning boshida shunchaki session'da userid bor-yo'qligini tekshiryapmiz (bu foydalanuvchi login qilganini bildiradi). Agar foydalanuvchi login qilgan bo'lsa, uni bosh sahifaga redirect qilamiz; aks holda login ekranini ko'rsatamiz. Login formasida post method'i bor va formani /process-login'ga yuboramiz. E'tibor bering, soddalik uchun javobda oddiy HTML satri qaytariladi, lekin real ilovada sizda katta ehtimol bilan alohida view fayli bo'ladi.
Avval bu sahifani ro'yxatdan o'tkazamiz, so'ng /process-login endpoint'ini amalga oshiramiz. Loyihaning root papkasidan index.js faylini oching va quyidagi route'ni ro'yxatdan o'tkazing:
const LoginHandler = require('./handlers/login.js');
app.get('/login', LoginHandler);
Keyin login formasi yuborilishini qayta ishlash funksionalligini amalga oshirishimiz kerak. Quyidagi tarkibga ega handlers/process-login.js faylini yarating:
module.exports = function processLogin(req, res) {
if (req.body.username !== 'admin' || req.body.password !== 'admin') {
return res.send('Invalid username or password');
}
req.session.userid = req.body.username;
res.redirect('/');
}
Ko'rib turganingizdek, foydalanuvchi muvaffaqiyatli authenticate bo'lishi uchun username va password mos ravishda admin va admin bo'lishi kerakligini shunchaki tekshiryapmiz. To'g'ri credential'lar topilganda, req.session.userid'ni yangilash orqali session'ga userid'ni yozamiz. Xuddi shunday, session'ga istalgan ma'lumotni yozishingiz mumkin. Masalan, agar foydalanuvchi role'ini saqlamoqchi bo'lsak, quyidagicha qilardik:
req.session.role = 'admin';
Va keyinchalik bu qiymatni keyingi so'rovlarning istalgan joyida session'dan olishimiz mumkin.
Bu route'ni loyihaning root papkasidagi index.js faylida ro'yxatdan o'tkazing:
const ProcessLoginHandler = require('./handlers/process-login.js');
app.post('/process-login', ProcessLoginHandler);
Nihoyat, logout funksionalligi qoldi. Quyidagi tarkibga ega handlers/logout.js faylini yarating:
module.exports = function Logout(req, res) {
req.session.destroy();
res.redirect('/');
};
Biz req.session.destroy()'ni chaqirib session'ni tozalaymiz va so'ng foydalanuvchini bosh sahifaga redirect qilamiz. Logout handler'ini index.js faylida quyidagicha ro'yxatdan o'tkazing:
const LogoutHandler = require('./handlers/logout.js');
app.get('/logout', LogoutHandler);
Ilovani ishga tushirish
package.json faylini oching va start script'ini quyidagicha ro'yxatdan o'tkazing:
"scripts": {
"start": "node index.js"
},
Endi quyidagi buyruqni bajarib ilovani ishga tushirishingiz mumkin:
npm run start
Endi brauzeringizni ochib, loyihaga http://localhost:3000 manzili orqali kirsangiz, session-based authentication'ning amalda ishlashini ko'rasiz.