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

Authentication policies #192

Open
filso opened this issue Oct 15, 2015 · 4 comments
Open

Authentication policies #192

filso opened this issue Oct 15, 2015 · 4 comments
Labels

Comments

@filso
Copy link

filso commented Oct 15, 2015

Hi @alexmingoia

Thank you for this router, works great.

I think policy-based access control would be very useful. Coupling this with router seems to have advantages. I'm currently implementing this for my project

Something like: http://sailsjs.org/documentation/concepts/policies

What do you think?

@alexmingoia
Copy link
Collaborator

As I understand it, policies are middleware that perform access control checks. That should work fine with koa-router. However, if you're using a rich DBMS like Postgres I think it's better to have access control logic at the DB rather than your application code.

@danneu
Copy link

danneu commented Nov 5, 2015

The router already exposes the most general solution possible by letting you plug your own middleware.

Sails.js ships with an authorization solution because one of its core goals is to be a prescriptive layer on top of Express, but koa-router is a lower-level building block.

For the same reason, Express' router doesn't come with an authorization abstraction.

@filso
Copy link
Author

filso commented Nov 9, 2015

@danneu agreed, it should be middleware

The problem is, as far as I'm aware, you can't attach any data to a particular route definition. It's just a route regexp and middleware / callbacks. So you can't say for example that '/home' should have some particular flags like "logged in only" that could be used by policy middleware.

I could use named routes, like that, and say that user route has particular qualities / access control list:
router.get('user', '/users/:id', policyMiddleware, function *(next) { });
but it seems there's still no way to find out that route user is matched from function body of policyMiddleware

@matthemsteger
Copy link

This can be accomplished via nested routers and middleware, if I understand what you are looking for correctly. For example, let's say you have an admin section of a web site that requires the admin role. All the routes in that section would go in an admin router. The admin router would call use and then build up the middleware that applies your policies.

let adminRouter = new Router({prefix: '/admin'});
adminRouter.use(getPolicyMiddleware(['policy1','policy2']); // this is just a function that returns your middleware that represents your policies, it can be composed any way you want.
adminRouter.get('/foo', function *(next) {}); // whatever you want here
baseRouter.use(adminRouter.routes()); // your base router

The policy middleware is just regular koa middleware that the router runs before it gets to your actual route. A basic example (assuming earlier in the pipeline you put on the state of the koa context whether the user is an admin or not, perhaps after establishing a session).

function *(next) {
    if (this.state.isAdmin) {
        yield next;
    } else {
        this.throw(403, 'You are not authorized.');
    }
}

I originally came from Sails too (it seemed like a good beginners library) and tried to apply the same concepts. Actually, if you want to get right down to it you can apply a dispatch layer over the router to apply whatever parameters and policies you want.

I use a simple dispatch to connect my koa-router routes with a controller. Something like ...

router.get.apply(router, dispatchToController('/some/url', 'controller/path', 'methodOnController', [policy1, policy2]));

The function returns an array of arguments that feed into the router, which basically amounts to a URL and a bunch of middleware to do whatever work we want. You could stick all your routes in whatever data structure you want, iterate over them and dispatch according to whatever convention you want.

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

No branches or pull requests

4 participants