Bir web uygulaması yazarken, o an uygulamayı kullanan kullanıcıyı bilmek istediğimiz bir çok durum vardır. Mesela en basitinden bir güzellik olsun diye kullanıcıya adı ile Hoşgeldin demek gibi. Örneğin Hoşgeldin Hasan. Evet basit bir örnek oldu fakat eğer bir bir kullanıcıyı sunucu ortamında takip edebilirsek, onun için özelleştirilmiş sayfalar da hazırlayabiliriz demektir.
Mesela bir blog sayfamız olduğunu düşünelim, eğer kullanıcıyı tanımlayabilirsek, onun yorum yapmasına veya yazı yazmasına izin verebiliriz, yada tam tersi. Bu nedenle session / oturum tanımlayarak yolumuza devam ederiz.
Oturum / Session Nedir?
Belirli bir süre için uygululamayı / web sayfasına gelen kullanıcıya bir kimlik atayarak sunucu tarafında takip ettiğimiz sürece oturum / session denir. Bu süreç belirlenen bir süreye kadardır. Sadece tekil bir kullanıcı için kullanılır. Genel olarak kullanıcı için tekil (uniq) bir kimlik (id) vererek sunucu tarafından takip edilir. Bu olay iki yönlü olarak işler, sunucu ve istemci arasında gerçekleşir
Özellikle bilgisayar bilimi ve ağ oluşturmada, bir oturum, zamanla sınırlı iki yönlü bir bağlantıdır, tcp/ip protokolünde iki veya daha fazla iletişim cihazı veya bilgisayar, otomatikleştirilmiş sistemler arasında etkileşimli ifade ve bilgi alışverişi sağlayan pratik bir katmandır. , veya canlı aktif kullanıcılar.
Wikipedia
Oturum Neden Gereklidir?
Bir bilgisayardaki uygulama çalıştığında kullanan kişi ve uygulama aynı bilgisayar üzerinde olduğu için kullanıcının kim olduğu kolaylıkla belirlenir ve sonrasında kullanıcı yetkilerine göre işlem yapılır. Fakat uygulamanın farklı bir bilgisayar (sunucu) üzerinde olduğunda ise durum farklıdır. Uygulama berlirli verileri tutabilir fakat asıl işlemler sunucu üzerinde yapıldığı için sunucunun da uygulamayı kimin kullandığından haberdar olması gereklidir. Bu özelleştirilmiş bir deneyim için önemli olduğu kadar, yetkisiz kullanımları engellemek için de önemlidir.
Mesela sunucu kullanıcının kim olduğunu bilmezse ona yönetici (admin) sayfalarını gösteremeyecektir. Giriş yapıldığında ikinci sayfaya girildiğinde yine kimin geldiğini tanımayacaktır. Bunun için istemci ve sunucu üzeri tanımlamalar yapmak gerekir.
Yine bir alışveriş sitesinde sepet bölümüne bir müşteri girdiğinde, kendi sepet içeriğini görebilmesi için sunucu tarafından müşterinin tanımlanması gerekmektedir. Bu sunucu veya istemci taraflı olarak yapılabilir.
Sunucu taraflı bir işlemde, kullanıcı ile ilgili bilgiler sunucu üzerinde tutulduğu için, kullanıcı adı, adresi, ziyaret ettiği sayfalar, sepet bilgileri, dışarıdan bir müdahaleye karşı korunaklı olacaktır. Bu nedenle de bir session / oturum açılması gerekli olur.
Express Session Paketi
Express JS ile bir uygulama geliştirirken oturum yönetimini kolayca yapmak için geliştirilmiş bir paket olan Express Session kullanılabilir. Bu özel olarak oturum yönetimi için geliştirildiğinden, geliştiriciye kolaylıklar sağlayan orta katman (middleware) paketidir.
Sayfa oluşturulmadan önce çağrılarak o an bir oturum olup olmadığı ve eğer varsa oturum açan kullanıcı bilgilerinin alınması için kullanılır. Oturum bilgileri ön tanımlı olarak RAM (hafıza) üzerinde tutulur. Fakat bu normal kullanımda sağlıklı bir yöntem değildir bu nedenle de bir çok veritabanı üzerinde verilerin tutulabilmesi için geliştirilmeler yapılmıştır.
Kurulum
Express Session bir npm paketidir ve bu nedenle kurulumu oldukça basittir. Bunun için komut satırından
npm install express-session
komutunun çalıştırılması yeterlidir. Uygulamaya eklenmesi için ise
const session = require('express-session');
şeklinde çağrılması yeterlidir. Artık session nesnesi ile işlemler yapmaya başlayabiliriz.
Örnek Kullanım
Ön tanımlı ayarlar ile bir session başlatmak için
const express = requrire('express');
const session = require('express-session');
const app = express();
app.use(session({
secret: 'fsad124asdfasdfs45343_5322asdfaSFAA',
resave: false,
saveUninitialized: true,
}))
şeklinde bir orta katman (middleware) olarak çağrılır. Session bilgilerine ulaşmak için requrest (istek) nesnesi üzerinden ulaşılabilir.
app.get("/", (req, res) => {
req.session.userID = 21314141;
if(req.session.isim === 'Hasan') {
...
}
})
Yukarıda hem session üzerinde bir değişkene atama yapmayı ve yine session üzerindeki bir değişkene ulaşmayı gördük. Oturum açıldıktan sonra oturuma atanan değişkenler kayıt edilir, ön tanımlı olarak ram hafızaya, yada ayarlama yapıldı ise bir veritabanına, sonrasında bir istek olduğunda çağrılabilir.
Örneğin bir basket nesnesi oluşturarak bir e-ticaret uygulamasında kullanıcının sepete attığı ürünleri tutabiliriz ve eğer kullanıcı sepet sayfasına girerse bu nesne üzerindeki bilgileri alarak sepet sayfası içeriğini doldurabiliriz.
**NOT : ** 1.5. sürümde sonra cookieParser kullanımına gerek kalamıştır. Eğer kullanılırsa bazı hatalar oluşabilir.
Kullanılan parametreleri incelersek.
- secret metin tabanlı oluşturulmuş özel bir güvenlik anahtarıdır. Genellikle uygulama için rastgele oluşturulan bir değer alır.
- resave oturum bilgilerinin eğer değerler değişmese bile her istekten sonra kayıt edilip edilmeyeceğini tanımlar. Eğer özel bir durum yoksa false olarak kullanılabilir.
- saveUninitialized başlatılmamış bir oturumu kayıt etmek için kullanılır. Eğer bir oturum üzerinde bir değişiklik yapılmadı ise o oturum başlatılmamıştır. Öylese kaydetmeye gerek yoktur. Bu nedenle özel bir durum yoksa false olarak ayarlamak gerekir.
Veritabanı Olarak Mongodb Kullanılması
Daha iyi bir deneyim için oturum bilgilerini bir veritabanında saklamak gerekli olacaktır. Express Session çok sayıda veritabanı ve sistemi desteklemektedir. Desteklenen sistemleri ve gerekli paketleri Github Sayfasından bulabilirsiniz. Biz bu bölümde Mongodb ile bir örnek vereceğiz.
Eğer oturum bilgilerini mongodb üzerinde saklayacaksak connect-mongo paketini uygulamamıza import etmemiz gerekmektedir. Connect-Mongo Express Session için geliştirilmiş oturum bilgilerini tutmak için MongoDB kullanımını sağlayan bir pakettir. Kurulumunu npm paket yöneticisini kullanarak yapabilirsiniz.
npm install connect-mongo
Connect-Mongo paketi yüklendikten sonra uygulamamıza import etmemiz gerekmektedir. Bunun için
const session = require('express-session');
const MongoStore = require('connect-mongo');
şeklinde MongoStoreu uygulamamıza import ediyoruz. Artık express-session için store ayarlamasını yapabiliriz.
const express = require('express');
const session = require('express-session');
const MongoStore = require('connect-mongo');
const app = express();
app.use(session({
secret: 'fsad124asdfasdfs45343_5322asdfaSFAA',
resave: false,
saveUninitialized: true,
store: MongoStore.create({
mongoUrl: 'mongodb://localhost:27017',
dbName: 'app-name'
});
}))
MongoStore oluşturulurken farklı parametreler almaktadır. Bunun için Github sayfasına bakılabilir. Burada
- mongoUrl ile Mongodb ile bağlantı kurmak için gerekli olan url, kullanıcı adı ve şifre gibi bilgileri girmek gerekmektedir. Örneğimizde localhost üzerindeki bir veritabanına bağlantı sağlayabiliriz.
- dbName ilede oturum bilgilerinin tutulacağı tablonun (koleksiyon) adını belirtebiliriz.
Bundan sora her oturum açıldığında ve oturuma bilgiler eklendiğinde, silindiğinde, değiştiğinde bu bilgiler mongodb üzerine kayıt edilecektir.
Bir Oturumu Bitirmek – Session.destroy
Bir oturum başlatıldığında belirli bir süre için etkin olacaktır. Bunu oturum oluştururken belirtiyoruz. Bu süre aşıldığında oturum sona erecektir. Fakat yine istediğimiz zaman da oturumu bitirebiliriz, mesela üye girişi yapmış bir kullanıcı, daha sonra üye çıkışı yaparsa, bu durumda oturumu bitirmemiz gerekmektedir. Bunu Session.destroy ile yapabiliriz.
req.session.destroy();
Tüm kayıtlı veriler silinecek ve sonrasında oturum sona erdirilecektir.
Express Session Paketinin Parametreleri
Bir oturum oluştururken alacağı parametreler bulunmakta. Bunlardan bir kaçtanesini daha önce belirttik. Şimdi diğerlerine bakalım.
cookie
Oturum çerezi ( cookie) için bir nesne oluşturur. Bu nesne bir kaç değer alır.
- cookie.domain oturum için geçerli olacak domain bilgisini içerir, Domain Set-Cookie değerini tanımlar. Eğer bir değer girilmezse genellikle istemciler (tarayıcı) bunu istek yapılan domain olarak kabul eder.
- cookie.expires oturum için oluşturulan cookie / çerezin ne zaman silineceğini belirtir, Expires Set-Cookie değerini tanımlar. Date nesnesi olarak değer verilir. Eğer bir değer girilmezse tarayıcı penceresi kapatıldığında oturum çerezleri silinir, bu da oturumun sona ermesi demektir.
- cookie.httpOnly sadece http olarak kullanılıp kullanılmayacağını belirtir, HttpOnly Set-Cookie değerini tanımlar. Boolean bir değer alır.
- cookie.maxAge çerezin yaşam süresinin en fazla ne kadar olacağını milisaniye olarak belirtir, Expires Set-Cookie değerini tanımlar. Ön tanımlı olarak bu tanımlama yapılmaz.
- cookie.path çerezin etkin olacağı yolu / path belirtir, Path Set-Cookie değerini tanımlar. Ön tanımlı olarak / değeri verilir.
- cookie.secure güvenli bağlantı olup olmayacağını belirtir, Secure Set-Cookie değerini tanımlar. Ön tanımlı olarak ayarlanmaz. Eğer tamamen güvenli bir bağlantı https üzerinde çalışılacaksa bu değerin true alarak ayarlanması önerilir. Aksi durumda true yapıldığında sorun oluşabilir.
NOT: Eğer expires ve maxAge birlikte tanımlandı ise, enson tanımlanan özellik kullanılır.
genid
Oturum ID değerini oluşturmak için bir callback fonksiyon tanımlamak için kullanılır. Aslında oturum ID değerini otomatik olarak oluşturulur ve bunun için uid-safe paketi kullanılır. Eğer farklı bir paket kullanılacaksa veya özel bir değer atanacaksa genid kullanılabilir.
app.use(session({
genid: function(req) {
return genuuid()
},
secret: 'ozel guvenli anahtar'
}))
name
Oturamu bir isim vermek için kullanılır. Ön tanımlı olarak bu değer ‘connect.sid’ şeklinde olacaktır. Özellikle aynı adreste birden fazla uygulama çalıştırılacaksa, isimlendirme yapılabilir.
store
Daha önce gördüğümüz gibi oturum bilgilerinin kayıt edileceği yeri ayarlar. Ön tanımlı olarak oturum bilgileri ram hafızada tutulur. Bunun için MemoryStore nesnesi kullanılır.
rolling
Oturumun sona erme süresini sıfırlar, bu şu demektir, eğer yeni bir istek olursa ve rolling değeri true olarak ayarlanmış ise, maxAge değeri ilk haline getirilir. Aksi halde oturum açıldığı anda belirlenen maxAge değeri, zaman geçtikçe, azalarak, sona gelindiğinde oturum bitirilecektir.
req.session
Oturum bilgileri response nesnesi üzerinde bulunan session nesnesi üzerinde tutulur. Bundan daha önce bahsetmiştik. Bu nesne üzerine istediğimiz bilgileri ekleriz ve gerektiğinde de bu bilgileri alırız. Mesela kullanıcı temasının light olarak ayarlanmasını istediğimizi düşünelim ve bunun için bu bilgiyi oturum üzerine kayıt etmek isteyebiliriz.
req.session.theme = 'light';
Sonrasında tema ayarlaması yaparken bu bilgiyi çağırabilir ve kullanabiliriz.
setTheme(req.session.theme);
Şeklinde sonrada çağırabiliriz. Burada setTheme örnek vermek amacı ile yazılmıştır.
Session.regenerate(callback)
Oturumu yeniden oluşturmak için kullanılır. Böylece yeni bir ID ile oturum yeniden oluşturulur ve gerekli değişkenler ayarlanır. Sonrasında callback fonksiyonu çağrılır.
req.session.regenerate(function(err) {
// ...
});
Session.reload(callback)
Eğer oturum bilgilerini yeniden oluşturulmak istenirse session.reload kullanılabilir. Böylece veritabanından oturum ile ilgili bilgiler tekrardan alınacak ve gerekli oturum bilgileri / değişkenleri yeniden oluşturulacaktır. Bu işlemden sonra callback fonksiyonu çağrılacaktır.
req.session.reload(function(err) {
// ...
});
Session.save(callback)
Hafızadaki oturum bilgisini veritabanına kayıt etmek için kullanılır. Normalde sunucu isteği cevapladığında bu işlem otomatik olarak yapılacaktır. Fakat istenirse save metodu kullanarak da yapılabilir.
req.session.save(function(err) {
// oturum kayıt edildi.
})
Session.destroy
Bir oturumu bitirmek için kullanılır. Bu metod çağrıldığında oturum bitirilir ve oturum ile ilgili tüm bilgiler silinir.
req.session.destroy();
Tüm kayıtlı veriler silinecek ve sonrasında oturum sona erdirilecektir.
req.session.id
Oturum ID değerini tutar. İhtiyaç olduğunda buradan alınabilir. Bu req.sessionID değerinin diğer adıdır. Oturum ID değeri tekildir ve benzersizdir.
req.session.cookie
Oturum ile ilgili çerez bilgilerinin tutulduğu nesnedir. Oturum çerezi ile ilgili maxAge gibi bilgileri tutar.
Yardımcı Kaynaklar
Express Session ile ilgili olarak aşağıdaki kaynaklara başvurabilirsiniz.
Sonuç
Uygulama bilgilerinin çerezlerde saklanması hem güvenlik açısından sorun teşkil eder ve hemde sınırlı bir kapasitesi olduğu için kullanışlı değildir. Bununla birlikte bir uygulama başlatıldığında gerekli verilerin sunucu üzerinde tutulması ile kullanıcıya özel içeriklerin sunulması oldukça kolaylaşır. Bu işleme oturum diyoruz.
Oturum oluşturma ile ilgili yaşadığınız sorunları ve çözümlerini bizimle paylaşır mısınız?
