Comment on page
Middleware
Middleware is an extremely important aspect of web applications as it allows you to run important code either before or after every request or even before or after certain routes. In this documentation we'll talk about how middleware works, how to consume middleware and how to create your own middlewar
Middleware classes are placed inside the
Kernel
class. All middleware are just classes that contain a before
method and after
method.There are four types of middleware in total:
- Middleware ran before every request
- Middleware ran after every request
- Middleware ran before certain routes
- Middleware ran after certain routes
We have one of two configuration attributes we need to work with. These attributes both reside in our
Kernel
file and are http_middleware
and route_middleware
.http_middleware
is a simple list which should contain your middleware classes. This attribute is a list because all middleware will simply run in succession one after another, similar to Django middlewareIn our
Kernel
file this type of middleware may look something like:from masonite.middleware import EncryptCookies
class Kernel:
http_middleware = [
EncryptCookies
]
Middleware will run on every inbound request to the application whether or not a route was found or not.
Route middleware is also simple but instead of a list, it is a dictionary with a custom name as the key and a list of middleware. This is so we can specify the middleware based on the key in our routes file.
In our
config/middleware.py
file this might look something like:from app.middleware.RouteMiddleware import RouteMiddleware
class Kernel:
#..
route_middleware = {
"web": [
SessionMiddleware,
HashIDMiddleware,
VerifyCsrfToken,
],
}
By default, all routes inside theweb.py
file will run theweb
middleware list
You can pass parameters from your routes to your middleware in cases where a middleware should act differently depending on your route.
You can do this with a
:
symbol next to your route middleware name and then pass in those parameters to the before
and after
middleware methods.For example, we may be creating a middleware for request throttling and in our routes we have something like this:
Get('/feeds', 'FeedController').middleware('throttle:2,100')
notice the throttle:2,100 syntax. The 2 and the 100 will then be passed into the before and after methods of your middleware:
class ThrottleMiddleware:
def before(self, request, response, minutes, requests):
# throttle requests
def after(self, request, response,
minutes, requests):
# throttle requests
Similiar to the way we can pass values to a middleware using the
:
splice we can also use the @
in the value to pass the value of the parameter.For example, we may create a route and a middleware like this
Get('/dashboard/@user_id/settings', 'FeedController').middleware('permission:@user_id')
If we go to a route like
/dashboard/152/settings
then the value of 152 will be passed to the middleware before and after methods.Middleware:
- can live anywhere in your project,
- Inherit from Masonite's base middleware class
- Contain a before and after method that accepts request and response parameters
from masonite.middleware import Middleware
class AuthenticationMiddleware(Middleware):
"""Middleware class
"""
def before(self, request, response):
#..
return request
def after(self, request, response):
#..
return request
It's important to note that in order for the request lifecycle to continue, you must return the request class. If you do not return the request class, no other middleware will run after that middleware.
That's it! Now we just have to make sure our route picks this up. If we wanted this to execute after a request, we could use the exact same logic in the
after
method instead.If we are using a route middleware, we'll need to specify which route should execute the middleware. To specify which route we can just append a
.middleware()
method onto our routes. This will look something like:Route.get('/dashboard', 'DashboardController@show').name('dashboard').middleware('auth')
Route.get('/login', 'LoginController@show').name('login')
Last modified 1yr ago