Peter Širka - Brutal Web Developer
Vytvorenie session middleware v Total.js za 5 minút

Mon Sep 05 2016 13:44:22 GMT+0200 (Central European Summer Time)

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
});

Značky


Posledné blogy
Brutálny polrok 2018
Fri Jun 22 2018 09:48:21 GMT+0200 (Central European Summer Time)
Konferencia/Workshop: TotalCon 2017
Thu Nov 16 2017 22:06:55 GMT+0100 (Central European Standard Time)
CodeCon 2017 z pohľadu organizátora
Sun Apr 09 2017 09:27:34 GMT+0200 (Central European Summer Time)
Elektrický bicykel KTM MACINA KAPOHO SLX 2017
Fri Mar 31 2017 15:32:37 GMT+0200 (Central European Summer Time)
Total.js platforma - školenia
Mon Jan 16 2017 18:35:05 GMT+0100 (Central European Standard Time)

Posledné komentáre
Thank you for your work! You are the great friend, great person and great expert!
Jozef Gula
Mon Jun 25 2018 08:02:14 GMT+0200 (Central European Summer Time)
It's been an absolute pleasure collaborating with you Peter, I've learned so much from Total.js a...
Pedro Costa
Fri Jun 22 2018 19:18:22 GMT+0200 (Central European Summer Time)
Tento skateboard až tak kopec nerieši, pretože má 2 silné motory. So mnou vyšiel všade, kde som b...
Peter Širka
Fri Jul 14 2017 09:30:56 GMT+0200 (Central European Summer Time)
Dobry den jak se vypořadavá s kopci ?
Lukáš
Thu Jul 13 2017 20:44:43 GMT+0200 (Central European Summer Time)
Chlapci z firmy Nazaret Pánu Bohu ďakujú a Tebe blahoželajú k dobre odvedenej práci. Super Peťo, ...
Tomáš
Thu Dec 15 2016 08:08:15 GMT+0100 (Central European Standard Time)