Está en la página 1de 5

cult t t .

co m

http://culttt.co m/2013/09/16/use-laravel-4-filters/

How to use Laravel 4 Filters


by Philip Bro wn

Last week we created the f unctionality to allow people to register and authenticate with Cribbb. Nearly all web applications require authentication in some f orm or another. Authentication is not just about restricting access to certain pages, but also restricting access to a wide array of user abilities. In order to write good web applications, its important to abstract this kind of f unctionality. You shouldnt have the logic to allow or disallow access to certain pages or methods scattered around your project because it will make maintaining it a nightmare. For example, imagine the criteria f or authenticating had to change in your web application, but the logic f or determining access was scattered around hundreds of f iles. It is inevitable that you will f orget to update certain aspects of your code, which could leave your application exposed to an attacker. Laravel 4 deals with this problem by abstracting this logic into Filters. Filters allow you to restrict access to a given route. T his means it is trivial to only allow admins to access the admin section of your website, or only allow registered user to POST a new piece of content. In this article we will be exploring the f ull f unctionality and usage of Laravel f ilters to see how they can keep our application saf e and secure.

What is a Filter?
A f ilter is basically a chunk of code that you will typically want to run either bef ore or af ter Laravel routes a request. So f or example, if you wanted to only allow registered users to access a certain route, you could attach an authentication f ilter that would determine if the current user is authenticated. When Laravel attempts to route the user to the request page, Laravel will automatically run your f ilter logic bef ore accessing the route. If a f ilter is returned a response, Laravel will action that response instead of the original request. So to protect restricted routes to only registered users, you would check to see if the current user is a guest. If the user is a guest you would return a redirect response to the login page. So as you can see, a f ilter is just an abstracted piece of logic that can be run bef ore or af ter a request is routed through the application. Laravel ships with a number of helpf ul f ilters already available to you. If you open up app/lt ers.php you will see a list of the pre-set f ilters.

Bef ore and Af ter


T he f irst two Filters you will see are the application Bef ore and Af ter f ilters: 1 2 3 App::before(funct ion($request ) { });

4 5 6 7 8 9

App::aft er(funct ion($request ,$response) { });

T hese two f ilters allow you to register code that you want to run bef ore or af ter each request. T hese two application events are part of the lif ecycle of each Laravel request. So f or example, if you wanted to record access requests to a log f ile, or you wanted to poll a services f or updates you could have this logic run automatically on every request.

The anatomy of a Filter


In order to understand how a f ilter works, lets break one down by look at one of the most important, the authentication f ilter: 1 2 3 4 Rout e::lt er('aut h',funct ion() { if (Aut h::guest ())ret urn Redirect ::guest ('login'); });

T he lt er method on the Rout e class accepts two arguments. T he f irst argument is the name of the f ilter, in this case auth. We need to give a f ilter a name so we can later attach it to a route. T he second argument is a Closure (What are PHP Lambdas and Closures?). T he Closure is where you store the logic f or this particular f ilter. So in the authentication f ilter above, Laravel checks to see if the current user is a guest. If the current user is a guest, the f ilter returns a redirect to the login page. If a f ilter returns a response, Laravel will route the request to the response, rather than the initial request.

Attaching a Filter to a Route


Once you have the f ilter set up, you need to attach it to a route in order f or it to take ef f ect. To attach a f ilter, simply pass it as an argument in the array of the second argument of a Rout e method def inition: 1 2 3 4 Rout e::get ('user/account ',array('before' =>'aut h', 'uses' =>'UserCont roller@account ', 'as' =>'user.account ' ));

In the example above Im attaching the auth f ilter to ensure only registered users can access the user account page.

To attach multiple f ilters, simply separate them with a pipe: 1 2 3 4 Rout e::get ('user/premium',array('before' =>'aut h|premium', 'uses' =>'UserCont roller@premium', 'as' =>'user.premium' ));

In this example Im checking that the user is both authenticated and is also a premium subscriber. An important thing to note about using multiple f ilters is, if the f irst f ilter f ails, all subsequent f ilters will be cancelled. T his makes sense in this situation because there is no point in checking to see if the current user is a premium subscriber if they are not authenticated. However, this is important to remember f or some routing and f iltering situations.

Pattern Filters
Attaching f ilters to each of your routes is going to get cumbersome pretty quickly. Fortunately, Laravel of f ers two ways to prevent unnecessary repetition. T he f irst method is to use a Pattern Filter: 1 2 3 4 5 6 In this example all URLS that are namespaced under the admin/* root will automatically have the admin f ilter applied. You may also restrict pattern f ilters to HT T P methods: 1 Rout e::when('post /*','aut h',array('post ','put ','delet e')); Rout e::lt er('admin',funct ion() { }); Rout e::when('admin/*','admin');

In this example only authenticated users would be able to create, edit or delete posts f rom the application.

Group Filters
Using a route pattern is perf ect when you want to attach a f ilter to a very specif ic set of routes like above. However its of ten the case that your routes wont f it into a nice pattern and so you would end up with multiple pattern def initions to cover all eventualities. A better solution is to use Group Filters: 1 2 3 Rout e::group(array('before' =>'aut h'),funct ion() { Rout e::get ('user/account ','UserCont roller@account ');

4 5 6 7 8

Rout e::get ('user/set t ings','UserCont roller@set t ings'); Rout e::get ('post /creat e','Post Cont roller@creat e'); Rout e::post ('post /st ore','Post Cont roller@st ore'); });

In this example all of the routes within the group will automatically have the authentication f ilter applied to them.

Filter classes
In all of the examples above, we used Closures to hold the logic of the f ilter. Laravel also allows you to create a specif ic class f or your custom def ined f ilter. Why would you want to do this? Well if you have many particular complex f ilters, it will probably make sense to abstract them away f rom the lt ers.php f ile to prevent that f ile f rom getting messy. T his will make organising and maintaining your f ilters a lot easier. Filter classes also use Laravels IoC Container. T his means that they will automatically be able to use dependancy injection so you can very easily test that they are working correctly. An example of a f ilter class could be: 1 2 3 4 5 6 7 8 9 10 11 You can then register you class based f ilter like this: 1 Rout e::lt er('api.aut h','ApiFilt er'); class ApiFilt er { public funct ion lt er() { if (!$t his->valid($access_t oken) ret urn Response::json(array( 'error' =>'Your access t oken is not valid' ), 403); } }

Conclusion
Filters allow you to very easily abstract complex route access logic into concise and easy to use nuggets of code. T his allows you to def ine the logic once, but then apply it to many dif f erent routes.

99% of all projects will end up using f ilters in one way or another. Whilst Ive f ocused primarily on authentication in this tutorial, f ilters can be applied in a wide variety of situations where you want to restrict access to a certain route based upon predef ined logic or you want to run a predef ined chunk of code bef ore or af ter certain requests. So instead of scattering this sort of logic throughout your application, abstract it to a f ilter that can be def ined once and be reused. T his will not only make your code clearer, but it will also be more maintainable and less likely to go wrong in the f uture if you are required to change the logic. T his is a series of posts on building an entire Open Source application called Cribbb. All of the tutorials will be f ree to web, and all of the code is available on GitHub.

También podría gustarte