Tell me more ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have a custom MVC framework that is in a constant state of evolution. There's a long standing debate with a co-worker how the routing should work. Considering the following directory structure:

/core/Router.php
/mvc/Controllers/{Public controllers}
/mvc/Controllers/Private/{Controllers requiring valid user}
/mvc/Controllers/CMS/{Controllers requiring valid user and specific roles}

The question is: "Where should the current User's authentication be established: in the Router, when choosing which controller/directory to load, or in each Controller?"

My argument is that when authenticating in the Router, an Error Controller is created instead of the requested Controller, informing you of your mishap; And the directory structure clearly indicates the authentication required.

His argument is that a router should do routing and only routing. Leave it to the Controller to handle it on a case by case basis. This is more modular and allows more flexibility should changes need to be made by the router.

PHP MVC - Custom Routing Mechanism alluded to it, but the topic was of a different nature.

Alternative suggestions would be welcomed as well.

share|improve this question
1  
I would agree with your co-worker. Keep the router simple and let it do just routing. You can still have any conventions you want, as per your path structure. in regards to authentication, you can have a parent controller called public_controller/private_controller and implement your authentication in there, depending on which controller you inherit from –  bumperbox Oct 9 at 0:37
 
i agree that the preference is the controller. but this assumes that your controllers are clearly broken out by role. whereas if you have controllers in your CMS that are available to different Roles - then consider what pinetree is suggesting. –  cartalot Oct 14 at 0:32

migrated from codereview.stackexchange.com Oct 8 at 23:11

This question came from our site for peer programmer code reviews.

2 Answers

I would go with your colleagues suggestion of leaving the Router to do its duty and not take others responsibility. I think its a good programming practice and would help others to understand the same as well.

Now, for the controllers, suggest you go ahead and use inheritance. Have a parent controller, Base_Controller, which can do all the chores which is common across all controllers. From Base, derive Secure_Controller and NonSecure_Controller, which does what the name states.

You can always throw an exception from the controller, which can well be handled by hooks to display the view gracefully.

share|improve this answer

I'd have another component in between that determines the access rights. This component can have a set of mappings of user roles to resources, where controllers and/or actions are the resources. The execution would then go like this:

Router -> Authorization -> Controller

Router: determines which controller and action to execute

Auth: find out which user role is logged in and check
if the user has access to the controller/action,
if not, throw an exception that will get caught by the error handler,
or redirect to login page for guests, or whatever

Controller: if the authorization component didn't complain, do work as usual

If you want to get fancy, you can use php doc comments and reflection to annotate your methods and controllers on the spot instead of having a big list of allowed resources for user roles. Something like:

class Controller {
    /**
     * @allow({'admin','user'})
     * @prevent({'guest'})
     */
    public function someAction(){}
}

The auth component can then read the annotations to determine access rights, instead of having a big list of role->resource mappings

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.