Vytvorenie session middleware v Total.js za 5 minút
Vytvoríme jednoduchý middleware
Nižšie uvedený kód môžete uložiť napr. do súboru your-app/definitions/session.js
:
const COOKIE = '__session';
const TIMEOUT = '10 minutes';
const SESSION = {};
F.middleware('session', function(req, res, next, options, controller) {
var cookie = req.cookie(COOKIE);
var ip = req.ip.hash().toString();
// A simple prevention for session hijacking
if (cookie) {
var arr = cookie.split('|');
if (arr[1] !== ip)
cookie = null;
}
if (!cookie) {
cookie = U.GUID(15) + '|' + ip;
// Writes cookie
res.cookie(COOKIE, cookie);
}
var session = SESSION[cookie];
if (session)
req.session = session;
else
SESSION[cookie] = req.session = {};
// Extends session timeout
req.session.ticks = F.datetime;
next();
});
// Clears expired sessions
F.on('service', function(counter) {
// each 2 minutes
if (counter % 2 !== 0)
return;
var ticks = F.datetime.add('-' + TIMEOUT);
Object.keys(SESSION).forEach(function(key) {
var session = SESSION[key];
if (session.ticks < ticks)
delete SESSION[key];
});
});
- konštanta
SESSION
obsahuje všetky aktívne relácie
- konštanta
TIMEOUT
obsahuje čas, za koľko expiruje relácia
- konštanta
COOKIE
obsahuje názov pre cookie
Čo sa vlastne robí tento middleware?
- príde request do middleware
- skontrolujeme, či existuje
cookie
s identifikátorom relácie v requeste
- ak existuje, tak následne urobíme malú kontrolu voči ukradnutiu session (len IP kontrola)
- ak neexistuje (alebo je podozrenie, že bola ukradnutá), tak vytvoríme nový identifikátor
- v kroku
var session = SESSION[cookie]
vraciame existujúcu session
- ďalej robíme kontrolu či session už existuje v pamäti (RAM) alebo nie
- následne ukončujeme middleware a framework pokračuje vo vyhodnotení trasy (routing)
Pod deklaráciou middleware je definovaná udalosť F.on('service', ....)
. Túto udalosť volá framework každú minutú a prostredníctom argumentu counter
vo funkcii v udalosti môžeme zistiť, koľké volanie udalosti práve nastáva. My vždy každú druhú minútu vymažeme relácie, ktoré sa už nepoužívajú (sú to všetky relácie, ktoré majú dobu nečinnosti väčšiu ako hodnota v konštante TIMEOUT
).
Použitie
Teraz nám už neostáva nič iné, ako použiť vytvorený middleware. Takže je potrebné vytvoriť/upraviť nejaký controller, napr. /your-app/controllers/default.js
:
exports.install = function() {
F.route('/', view_index, ['#session']);
};
function view_index() {
// this === controller
var self = this;
if (self.session.counter === undefined)
self.session.counter = 0;
self.session.counter++;
self.view('index');
}
Čo sa vlastne robí vo vyššie uvedenom kóde?
- vytvoríme trasu na úvodnú stránku
F.route('/', action, [flags])
- trasa obsahuje
session
middleware, ktorý sme vytvorili
- následne v akcii môžeme použiť objekt
controller.session
Po príchode request
na úvodnú stránku sa vyvolá najprv middleware
session a následne sa volá akcia v trase. Middleware nemusíme definovať do trasy, ale môžeme ho nastaviť pre všetky trasy pomocou funkcie F.use()
- viac v dokumentácii.
Rozšírenie middleware o napr. udalosti
Teraz je už veľmi jednoduché rozšíriť funkčnosť middleware o hocičo. Nižšie uvedený kód rozširujem o udalosti, takže jednoducho budeme vedieť zachytiť, keď sa bude vytvárať nová session a keď session expiruje.
F.middleware('session', function(req, res, next, options, controller) {
// ...
// ...
// ...
var session = SESSION[cookie];
if (session)
req.session = session;
else {
SESSION[cookie] = req.session = {};
// Vždy, keď sa vytvorí nová session, tak sa vyvolá event "session-new"
F.emit('session-new', req, res);
}
// ...
// ...
// ...
});
// Clears expired sessions
F.on('service', function(counter) {
// ...
// ...
// ...
Object.keys(SESSION).forEach(function(key) {
var session = SESSION[key];
if (session.ticks < ticks) {
delete SESSION[key];
// Vždy, keď expiruje existujúca session, tak sa vyvolá event "session-remove"
F.emit('session-remove', session);
}
});
// ...
// ...
// ...
});
Použitie:
Nižšie uvedený kód môžete použiť v každom .js
súbore na server-side v Total.js.
F.on('session-new', function(req, res) {
// nový užívateľ
});
F.on('session-remove', function(session) {
// session je neaktívna
});