Unfortunately this doesnt work. I do not see any json output on before(). If I move the auth check to a regular method, it works fine, but then id have to add it to all methods.
Someone on irc suggested using die, and that gave output to the browser, but it wasn't reading the rest config file for some reason. Only after I set protected $format="json" did die($this->response(array(array('error' => 'not logged in'))) return json.
So even though i could just do the auth check in all the methods, or use die() in the before method, that seems suboptimal. Am I doing something wrong here or misunderstanding?
As the docs state, you should not use before() to make routing descisions. In other works, to alter the request flow in the controller. It can only be used for generic prepping code (that has to be executed before every method in the controller).
Because if this, it's pointless to return anything, it will be discarded.
If you want central security control, use the router() method. That does allow you to return data. If the check passes, just call parent::router() to continue the execution flow (make sure to pass all arguments!).
Hi Harro, one more question about this. I am doing several things in before() like CSRF checks, auth checks, etc. Only after these checks pass, do I do 'generic prepping' like setting up some class objects.
Since I cant return a failure in before() I have to move the checks to router(), but this means I have to move everything to router() and before() is no longer used. To me this seems to be the case in all situations where you want to do these kinds of global checks. So why does before() exist at all? One may as well always use router() right?
before() is more useful in Controller_Template and Controller_Hybrid when it comes to interactive output (i.e. to the browser). There you can use it to load static partials, set titles, and other prep stuff for the page you're about to output.
With Controller_Rest the before() is used to determine the format to be returned, and to setup a response object. In API controllers using this base controller there isn't much else you can do in before(). The base controller itself does everything in router() as well.
For both, it is best practice to only use before() for prepping, and router() for routing descisions. And access validation (that could cause such a descision if no access is granted) is something we think should be in router().
But since in an interactive environment you CAN break out (using a redirect), most people use the before() for this purpose, as it saves you from retrieving the called method and have router call that. For REST however, it already has a router() method, so all you have to do is do you validations, return an error if it fails, or call parent::router() if access it granted.