How to create custom authorization mechanism?

Mon Nov 14 2016 15:47:33 GMT+0100 (Central European Standard Time), Peter Širka

How to create custom authorization mechanism?

After reading you won't need any authorization module for your web applications, just learn from this blog post and you will have everything under control.

Definition of authorization

Create a definition file e.g. /definitions/auth.js:

// This object will contain all online users (their sessions)
const ONLINE = {};

// Cookie name
const COOKIE = '__user';

// A secret for encryption
const SECRET = 'js.latoT';

// Session expiration
const EXPIRE = '20 minutes';

// Total.js authorize delegate is executed on each request with except for a request to a static file
F.onAuthorize = function(req, res, flags, callback) {

    var cookie = req.cookie(COOKIE);

    // Check the cookie length
    if (!cookie || cookie.length < 20)
        return callback(false);

    // Decrypt the cookie value
    cookie = F.decrypt(cookie, SECRET);
    if (!cookie)
        return callback(false);

    // Look into the session object whether the user is logged in
    var session = ONLINE[cookie.id];
    if (session) {
        // User is online, so we increase his expiration of session
        session.ticks = F.datetime;
        return callback(true, session);
    }

    // Session doesn't exist here, so we try to sign-in user because we have his ID
    var sql = DB();

    sql.select('user', 'tbl_user').make(function(filter) {
        filter.where('id', cookie.id);
        filter.where('blocked', false);
        filter.where('confirmed', true);
        filter.where('removed', false);
        filter.first();

        // User session will contain these properties:
        filter.fields('id', 'name', 'photo');
    });

    sql.exec(function(err, response) {

        // Check whether the user exists in DB
        if (err || !response.user) {
            // If not, then remove the cookie
            res.cookie(COOKIE, '', '-1 day');
            return callback(false);
        }

        var user = response.user;

        // We have the user so we can set the current timestamp (for his expiration)
        user.ticks = F.datetime;

        // Create a session
        ONLINE[user.id] = user;

        // Authorize the user
        callback(true, user);
    });
};

// A simple service cleaner for expired sessions
F.on('service', function(counter) {

    // Clean session each 5 minutes
    if (counter % 5 !== 0)
        return;

    var sessions = Object.keys(ONLINE);

    //  Set 'ticks' to -20 minutes from now 
    var ticks = F.datetime.add('-' + EXPIRE);

    for (var i = 0, length = sessions.length; i < length; i++) {
        var session = ONLINE[sessions[i]];

        // Sessions will be removed when are older than "-20 minutes"
        if (session.ticks < ticks)
            delete ONLINE[sessions[i]];
    }

});

// A simple login method for creating an auth cookie
F.userlogin = function(controller, id) {

    var user = {};
    user.id = id;
    user.ticks = F.datetime.getTime();

    // We can add another security elements e.g.: User-Agent, IP address, etc.
    // user.ip = controller.ip;

    controller.cookie(COOKIE, F.encrypt(user, SECRET), '7 days');
    return F;
};

// The method removes auth cookie
F.userlogoff = function(controller) {
    controller.cookie(COOKIE, '', '-1 day');
    return F;
};

How to use it in a controller?

exports.install = function() {
    // Unauthorized
    F.route('/login/',   login,   ['unauthorize', 'post']);

    // Authorized
    F.route('/logoff/',  logoff,  ['authorize']);
    F.route('/account/', account, ['authorize']);
};

function login() {
    var self = this;   

    // Only what we need is a user ID
    // We have to obtain it from e.g. database
    var iduser = 1;

    // The method below creates an authorization cookie
    F.userlogin(self, iduser);

    // Redirect user to his account
    self.redirect('/account/');
}


function logoff() {
    var self = this;

    // The method below removes an authorization cookie
    F.userlogoff(self);

    // Redirect a user to a login page
    self.redirect('/login/');
}

// How to get the user session? It's easy:
function account() {
   var self = this;   
   console.log(self.user);
   // or view e.g. @{user.name}
   self.view('account');
}

How to increase security?

Documentation


Tags

Follow us

Latest blogs
A critical security fix
Wed Feb 13 2019 22:15:39 GMT+0100 (Central European Standard Time)
New release: Total.js v3.2
Wed Feb 13 2019 22:14:39 GMT+0100 (Central European Standard Time)
Total.js Wiki v2
Fri Jan 04 2019 22:15:01 GMT+0100 (Central European Standard Time)
Total Year 2018
Thu Jan 03 2019 21:14:00 GMT+0100 (Central European Standard Time)
Total.js Code Editor v1
Fri Dec 07 2018 22:55:13 GMT+0100 (Central European Standard Time)

Latest comments
Nice tip
Mauro Junior
Thu Sep 20 2018 21:41:02 GMT+0200 (Central European Summer Time)
Not only for Total.js. You can communicate with different websocket servers.
Peter Širka
Mon Apr 23 2018 20:08:20 GMT+0200 (Central European Summer Time)
Marko: you need to create a buffer with this codepage and write byte-to-byte string. I recommend ...
Peter Širka
Mon Apr 23 2018 20:06:21 GMT+0200 (Central European Summer Time)
Is WEBSOCKETCLIENT only for internal ws connections between totaljs apps?
Stelios Stephanua
Fri Mar 16 2018 06:04:22 GMT+0100 (Central European Standard Time)
Total.js is amazing! ;)
Leonardo Hessel
Tue Dec 19 2017 19:51:15 GMT+0100 (Central European Standard Time)

Pixabay


Read more

A critical security fix

News: We were notified about the critical security bug in Total.js framework. Read a prevention.

Wed Feb 13 2019 22:15:39 GMT+0100 (Central European Standard Time)
New release: Total.js v3.2

News: This new release brings a critical security fix and small new improvements. Update Total.js now.

Wed Feb 13 2019 22:14:39 GMT+0100 (Central European Standard Time)
Total.js Wiki v2

Products: I have released a new version of Total.js Wiki. New version brings new improvements.

Fri Jan 04 2019 22:15:01 GMT+0100 (Central European Standard Time)
Total Year 2018

Business: Last year was perfect for Total.js platform. Total.js platform grows up and it has great results.

Thu Jan 03 2019 21:14:00 GMT+0100 (Central European Standard Time)
Total.js Code Editor v1

Products: Try our real-time collaboration tool for Total Developers. Code Editor offers great features for development.

Fri Dec 07 2018 22:55:13 GMT+0100 (Central European Standard Time)
New release: Total.js v3.1

News: I have released a new version of Total.js with bug fixes and with small improvements.

Fri Dec 07 2018 11:41:40 GMT+0100 (Central European Standard Time)