2017-06-23 01:43:19 +02:00
|
|
|
title: HTTP Middlewares
|
|
|
|
summary: Create objects for modifying request and response objects across controllers.
|
|
|
|
|
|
|
|
# HTTP Middlewares
|
|
|
|
|
|
|
|
HTTP Middlewares allow you to put code that will run before or after. These might be used for
|
|
|
|
authentication, logging, caching, request processing, and many other purposes. Note this interface
|
2017-07-10 00:19:17 +02:00
|
|
|
replaces the SilverStripe 3 interface [RequestFilter](api:SilverStripe\Control\RequestFilter), which still works but is deprecated.
|
2017-06-23 01:43:19 +02:00
|
|
|
|
2017-07-10 00:19:17 +02:00
|
|
|
To create a middleware class, implement `SilverStripe\Control\Middleware\HTTPMiddleware` and define the
|
|
|
|
`process(HTTPRequest $request, callable $delegate)` method. You can do anything you like in this
|
2017-06-25 05:12:29 +02:00
|
|
|
method, but to continue normal execution, you should call `$response = $delegate($request)`
|
|
|
|
at some point in this method.
|
2017-06-23 01:43:19 +02:00
|
|
|
|
2017-07-10 00:19:17 +02:00
|
|
|
In addition, you should return an `HTTPResponse` object. In normal cases, this should be the
|
|
|
|
`$response` object returned by `$delegate`, perhaps with some modification. However, sometimes you
|
2017-06-23 01:43:19 +02:00
|
|
|
will deliberately return a different response, e.g. an error response or a redirection.
|
|
|
|
|
|
|
|
**mysite/code/CustomMiddleware.php**
|
|
|
|
|
2017-07-10 00:19:17 +02:00
|
|
|
```php
|
2017-11-20 01:10:37 +01:00
|
|
|
use SilverStripe\Control\Middleware\HTTPMiddleware;
|
2017-07-10 00:19:17 +02:00
|
|
|
use SilverStripe\Control\HTTPRequest;
|
2017-06-23 01:43:19 +02:00
|
|
|
|
2017-07-10 00:19:17 +02:00
|
|
|
class CustomMiddleware implements HTTPMiddleware
|
|
|
|
{
|
|
|
|
public $Secret = 'SECRET';
|
2017-06-23 01:43:19 +02:00
|
|
|
|
2017-07-10 00:19:17 +02:00
|
|
|
public function process(HTTPRequest $request, callable $delegate)
|
|
|
|
{
|
|
|
|
// You can break execution by not calling $delegate.
|
|
|
|
if ($request->getHeader('X-Special-Header') !== $this->Secret) {
|
|
|
|
return new HTTPResponse('You missed the special header', 400);
|
|
|
|
}
|
2017-06-23 01:43:19 +02:00
|
|
|
|
2017-07-10 00:19:17 +02:00
|
|
|
// You can modify the request before
|
|
|
|
// For example, this might force JSON responses
|
|
|
|
$request->addHeader('Accept', 'application/json');
|
2017-06-23 01:43:19 +02:00
|
|
|
|
2017-07-10 00:19:17 +02:00
|
|
|
// If you want normal behaviour to occur, make sure you call $delegate($request)
|
|
|
|
$response = $delegate($request);
|
2017-06-23 01:43:19 +02:00
|
|
|
|
2017-07-10 00:19:17 +02:00
|
|
|
// You can modify the response after it has been generated
|
|
|
|
$response->addHeader('X-Middleware-Applied', 'CustomMiddleware');
|
2017-06-23 01:43:19 +02:00
|
|
|
|
2017-07-10 00:19:17 +02:00
|
|
|
// Don't forget to the return the response!
|
|
|
|
return $response;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
2017-06-23 01:43:19 +02:00
|
|
|
|
2017-07-10 00:19:17 +02:00
|
|
|
Once you have created your middleware class, you must attach it to the `Director` config to make
|
2017-06-23 01:43:19 +02:00
|
|
|
use of it.
|
|
|
|
|
|
|
|
## Global middleware
|
|
|
|
|
2017-07-10 00:19:17 +02:00
|
|
|
By adding the service or class name to the `Director.Middlewares` property via injector,
|
2017-06-25 05:12:29 +02:00
|
|
|
array, a middleware will be executed on every request:
|
2017-06-23 01:43:19 +02:00
|
|
|
|
|
|
|
**mysite/_config/app.yml**
|
|
|
|
|
2017-06-25 05:12:29 +02:00
|
|
|
|
2017-07-10 00:19:17 +02:00
|
|
|
```yaml
|
|
|
|
---
|
|
|
|
Name: myrequestprocessors
|
|
|
|
After:
|
|
|
|
- requestprocessors
|
|
|
|
---
|
|
|
|
SilverStripe\Core\Injector\Injector:
|
|
|
|
SilverStripe\Control\Director:
|
|
|
|
properties:
|
|
|
|
Middlewares:
|
|
|
|
CustomMiddleware: %$CustomMiddleware
|
|
|
|
```
|
2017-06-25 05:12:29 +02:00
|
|
|
|
2017-06-23 01:43:19 +02:00
|
|
|
|
|
|
|
Because these are service names, you can configure properties into a custom service if you would
|
|
|
|
like:
|
|
|
|
|
|
|
|
**mysite/_config/app.yml**
|
|
|
|
|
2017-07-10 00:19:17 +02:00
|
|
|
```yaml
|
|
|
|
SilverStripe\Core\Injector\Injector:
|
|
|
|
SilverStripe\Control\Director:
|
|
|
|
properties:
|
|
|
|
Middlewares:
|
|
|
|
CustomMiddleware: %$ConfiguredMiddleware
|
|
|
|
ConfiguredMiddleware:
|
|
|
|
class: 'CustomMiddleware'
|
|
|
|
properties:
|
|
|
|
Secret: "DIFFERENT-ONE"
|
|
|
|
```
|
2017-06-23 01:43:19 +02:00
|
|
|
|
|
|
|
## Route-specific middleware
|
|
|
|
|
|
|
|
Alternatively, you can apply middlewares to a specific route. These will be processed after the
|
2017-06-25 05:12:29 +02:00
|
|
|
global middlewares. You can do this by using the `RequestHandlerMiddlewareAdapter` class
|
|
|
|
as a replacement for your controller, and register it as a service with a `Middlewares`
|
|
|
|
property. The controller which does the work should be registered under the
|
|
|
|
`RequestHandler` property.
|
2017-06-23 01:43:19 +02:00
|
|
|
|
|
|
|
**mysite/_config/app.yml**
|
|
|
|
|
2017-07-10 00:19:17 +02:00
|
|
|
```yaml
|
|
|
|
SilverStripe\Core\Injector\Injector:
|
|
|
|
SpecialRouteMiddleware:
|
|
|
|
class: SilverStripe\Control\Middleware\RequestHandlerMiddlewareAdapter
|
|
|
|
properties:
|
|
|
|
RequestHandler: %$MyController
|
|
|
|
Middlewares:
|
|
|
|
- %$CustomMiddleware
|
|
|
|
- %$AnotherMiddleware
|
|
|
|
SilverStripe\Control\Director:
|
|
|
|
rules:
|
|
|
|
special\section:
|
|
|
|
Controller: %$SpecialRouteMiddleware
|
|
|
|
```
|
2017-06-23 01:43:19 +02:00
|
|
|
|
|
|
|
## API Documentation
|
|
|
|
|
2017-07-10 00:19:17 +02:00
|
|
|
* [HTTPMiddleware](api:SilverStripe\Control\Middleware\HTTPMiddleware)
|