Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authentication and authorization with Flatiron's Resourceful & Restful

I want to implement authentication and authorization in the Flatiron stack (using Flatiron, Resourceful and Restful). I want to require that a user has the necessary permissions, when trying to change a resource. In the Restful Readme file, there's a note about authorization:

There are several ways to provide security and authorization for accessing resource methods exposed with restful. The recommended pattern for authorization is to use resourceful's ability for before and after hooks. In these hooks, you can add additional business logic to restrict access to the resource's methods.

It is not recommended to place authorization logic in the routing layer, as in an ideal world the router will be a reflected interface of the resource. In theory, the security of the router itself should be somewhat irrelevant since the resource could have multiple reflected interfaces that all required the same business logic.

TL;DR; For security and authorization, you should use resourceful's before and after hooks.

So authorization can be handled by Resourceful's hooking system.

My actual problem is the authentication process at the beginning of every HTTP request.

Let's say I have a resource Post, a User and a resource Session. The REST API is being defined by using Restful. My main concern for this question is to ensure that a user has a session when creating a post. Other methods like save, update or for other resources like creating a user should work analogous.

File app.js:

var flatiron = require('flatiron');
var app = flatiron.app;

app.resources = require('./resources.js');

app.use(flatiron.plugins.http);
app.use(restful);
app.start(8080, function(){
  console.log('http server started on port 8080');
});

File resources.js:

var resourceful = require('resourceful');

var resources = exports;

resources.User = resourceful.define('user', function() {
  this.restful = true;
  this.string('name');
  this.string('password');
});

resources.Session = resourceful.define('session', function() {
  // note: this is not restful
  this.use('memory');
  this.string('session_id');
});

resources.Post = resourceful.define('post', function() {
  this.restful = true;
  this.use('memory');
  this.string('title');
  this.string('content');
});

resources.Post.before('create', function authorization(post, callback) {
  // What should happen here?
  // How do I ensure, a user has a session id?

  callback();
});

There's also a runnable version of the code (thanks @generalhenry).

So assume a user trying to create a post, already has been given a session id, that is sent with every request he makes by a cookie header. How can I access that cookie in the before hook (i.e. the authorization callback)?

The example can be started with node app.js and HTTP requests can be made using curl.

like image 361
pvorb Avatar asked Oct 04 '22 17:10

pvorb


1 Answers

Keep in mind that these guidelines are for authorization process. If you need to use sessionId you can access it either way: req.sessionID, req.cookies["connect.sid"].

By checking requests this way you will be sure every users have valid session id.

app.use(flatiron.plugins.http, {
  before: [
    connect.favicon(),
    connect.cookieParser('catpsy speeds'),
    function(req, res) {
      if (req.originalUrl === undefined) {
        req.originalUrl = req.url;
      }
      res.emit('next');
    },
    connect.session({secret : 'secter'}),
    function(req, res) {
      console.log('Authenticating...');
      console.dir(req.session);
      //any other validation logic
      if (req.url !== '/login' && typeof req.session.user == 'undefined') {
        res.redirect('/login');
      } else {
        res.emit('next');
      }
    }
  ]
});

Here is project example using this approach.

like image 125
jan salawa Avatar answered Oct 13 '22 03:10

jan salawa