Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable authentication #54

Closed
lughino opened this issue Jun 6, 2015 · 4 comments
Closed

Enable authentication #54

lughino opened this issue Jun 6, 2015 · 4 comments

Comments

@lughino
Copy link

lughino commented Jun 6, 2015

As per specifications jsonrpcx, it would be interesting to add an example of how to implement an authentication system.

It would be very welcome also the possibility to manage the methods as middleware, in order to separate the layer of validation from the rest of the method.

@tedeh
Copy link
Owner

tedeh commented Jun 16, 2015

I'm not to keen on that jsonrpcx extension and I believe that a system for authentication should be handled within JSON-RPC without the need for extensions. It would be easy to do something like this (not checked for validity):

var jayson = require('jayson');

var methods = {
  protected_method: authed(function(args, done) {
    // do something
    done();
  })
};

var server = jayson.server(methods, {
  collect: true, // all params in one argument
  params: Object // params are always an object
});

// bless a fn with auth parameters
function authed(fn) {
  return function(args, done) {
    var auth = args.auth;
    // validate auth token
    return fn.call(this, args, done); // pass on like a middleware
  };
}

@tedeh tedeh closed this as completed Jun 16, 2015
@ShaggyDev
Copy link

I know that this issue is over a year old now but I am currently evaluating using jayson to implement rpc and and currently dealing with how I can secure individual endpoints. @tedeh Your example is spot on for creating that middleware to validate authentication before running the method logic. In my special case, I am using the "jayson/promise" server so that the services I already have setup to return promises will still work without having to attach the extra "then" block to return the result of the promise in a callback. When clamping the "authed" function around the original function, the option to return a resolved promise no longer seems to work and have to resort to returning the resolved promise result in the callback. Is there something I am missing that can turn the implementation above to support the promise ability of "jayson/promise"?

@tedeh
Copy link
Owner

tedeh commented Jul 29, 2016

This works for me:

var jayson = require('../../promise');
var _ = require('lodash');

var server = jayson.server({
  add: authed(function(args) {
    return new Promise(function(resolve, reject) {
      var sum = _.reduce(args, (sum, value) => sum + value, 0);
      resolve(sum);
    })
  })
});

server.http().listen(3000);

function authed(fn) {
  return function(args) {
    return new Promise(function(resolve, reject) {
      const isValid = Math.random() >= 0.5;
      if(isValid) {
        // key line: pass resolve and reject to promise returned by fn
        fn(args).then(resolve, reject);
      } else {
        reject({code: 5, message: 'invalid credentials provided'});
      }
    })
  }
}

@ShaggyDev
Copy link

ShaggyDev commented Jul 29, 2016

Thanks man, this was the missing link I was looking for. TBH this was the first time I have had the need to look at these middleware-like functions and manipulate them so this helps a lot. With some slight modification to your above example, I have it setup where the body of the original function only needs to return the value we want in the result field of the response instead of having to wrap the body of the method in a new Promise. Here is what I converged on:

var jayson = require('../../promise');
var _ = require('lodash');

var server = jayson.server({
  add: authed(function(args) {
    return _.reduce(args, (sum, value) => sum + value, 0);
  })
});

server.http().listen(3000);

function authed(fn) {
  return function(args) {
    return new Promise(function(resolve, reject) {
      const isValid = Math.random() >= 0.5;
      if(isValid) {
        // key line: pass resolve and reject to promise returned by fn
        resolve(fn(args));
      } else {
        reject({code: 5, message: 'invalid credentials provided'});
      }
    })
  }
}

The only difference here is really just a matter of preference and implementation I guess.

Thank you for responding back on this and for keeping up this package, it has been pretty easy to work with so far and the documentation already provided does a swell job in answering most questions I would have had.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants