jaredhanson / locomotive

Powerful MVC web framework for Node.js.
http://locomotivejs.org/
MIT License
888 stars 135 forks source link

can draw route after the httpserver started? #176

Closed gentlecolder closed 8 years ago

gentlecolder commented 9 years ago

because i need dynamic draw the routes according user kind in the request

jaredhanson commented 9 years ago

Can you please describe the use case in more detail? In what situations would this be beneficial, and have you considered alternative ways to implement such functionality?

gentlecolder commented 9 years ago

thank u for your response, the case actully i mentioned above. normally when client request come in, we need know the user kind or userType, then we can designed to give the user or client the functions..For example, a user type is the admin account, and this account must has the previlige of the function which can adding or deleting resource, and the normal userType not have the function. so here if the request come in, first get the user level, second draw the route to provide the functions. but the httpserver is still not started how can i get the userType in request.

crispen-smith commented 9 years ago

Just my $0.02, but that doesn't sound like it drives any need to redraw the routes.

Instead, draw all of your possible routes prior to starting your HTTP server and then set up a filter within the controller functions to prevent unauthorized access.

There are many great existing filters out there, but I find that most of the time something like

fooController.before("*", function (next) { getUser() //in an appropriate fashion if(user.access.is_not_appropriate) { redirect("foo/error"); } else { next(); } }

fooController.someAction = function() {};

is really all you need.

gentlecolder commented 9 years ago

yes your method can working, but that would write the same code in many controllers, and if the mount of the controllers is large, that would be result in copying many code in every needed controller and every needed controller need to execute the user type judgement code repeatedly, that would be result in add the server's burden in theory。

crispen-smith commented 9 years ago

Agreed, but most of the time the server is started once as a static resource that sits in memory waiting for requests. A server restart would only (normally; at least for web server instances) happen due to a code change. If I'm visualizing what you're suggesting it looks like you want to restart your server every time a user logs in. This a) breaks sessions for all other visitors and b) is a much heavier load on the machine than having all of the code required to describe every use case.

You should however only write the filter once and call it as a prehook filter for all instances.

gentlecolder commented 9 years ago

pls change the structure of locomotive and let the drawing route run after httpserver started to fit the mvc design logic and prevent it from server setting.

gentlecolder commented 9 years ago

Hi draw route should in mvc designing phase, not in http server setting phase. so I still ask u if can chang the order of the modules in everyone normal logical opinion

At 2015-05-19 14:43:34, "Jared Hanson" notifications@github.com wrote:

Can you please describe the use case in more detail? In what situations would this be beneficial, and have you considered alternative ways to implement such functionality?

— Reply to this email directly or view it on GitHub.

OtaK commented 9 years ago

There's no logical motive behind dynamic route loading. Just use ACL/custom middlewares if you need to handle route existence on a per-user basis. If the route is not supposed to exist for that user, send a 404.

I'm doing something in those lines, a custom middleware checking user type when a request is made on some controllers.

var _roles = ['USER', 'MOD', 'SU'];
module.exports.acl = function(minLevel) {
    return function(next) {
        if (!this.req.user) // note that I'm using passport.js for authentication
            return this.res.send(403);

        if (_roles.indexOf(this.req.user.type) < _roles.indexOf(minLevel))
            return this.res.send(404);

        return next();
    };
};

// And then in your controller
myController.before(['your', 'methods', 'to', 'protect'], function(next) {
     this.app._middlewares.acl('SU').bind(this)(next);
});
crispen-smith commented 9 years ago

I think, from a ux perspective at least, that a naked 404 is probably less ideal that a custom 404 and routing the request to your error responder for the controller, from a headers perspective a 404 is great though.

gentlecolder commented 8 years ago

ok, now i would be close this issue