Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Middleware: Between the Framework and the Browser

Middleware: Between the Framework and the Browser

Discussing what Middleware is and how to use Middleware in PHP, using the PSR-15 standard.

Justin Yost

June 06, 2019
Tweet

More Decks by Justin Yost

Other Decks in Programming

Transcript

  1. Middleware: Between the Framework and the Browser Justin Yost Lead

    Software Engineer Wirecutter CC BY-NC 4.0 Justin Yost 1
  2. Middleware • What is middleware? Software that sits in-between (or

    in the middle) between our normal PHP application and the browser. CC BY-NC 4.0 Justin Yost 2
  3. Middleware • Middleware is designed to act upon Requests and

    Responses and do something. • The do something is left up to you, modify the Request/ Response, stop it, redirect it, etc. CC BY-NC 4.0 Justin Yost 3
  4. Middleware Use Cases • Caching • Rate Limiting • CORS

    Headers • Logging • CSRF • IP Blocking • https://github.com/oscarotero/psr7-middlewares • https://github.com/lalop/awesome-psr7 CC BY-NC 4.0 Justin Yost 5
  5. Middleware Can and Can Nots • Can • Modify Requests

    • Modify Responses • Can Not • ! CC BY-NC 4.0 Justin Yost 6
  6. Middleware • Build logic external to the application like Rate

    Limiting into Middleware • Build say a standard set of responses for generic queries into Middleware • Build an entire CRUD application using Middleware, sure. CC BY-NC 4.0 Justin Yost 7
  7. Middleware Design • PSR-15: HTTP Server Request Handlers • Uses

    PSR-7: Requests/Responses CC BY-NC 4.0 Justin Yost 8
  8. namespace Psr\Http\Server; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface;

    /** * Participant in processing a server request and response. * * An HTTP middleware component participates in processing an HTTP message: * by acting on the request, generating the response, or forwarding the * request to a subsequent middleware and possibly acting on its response. */ interface MiddlewareInterface { /** * Process an incoming server request. * * Processes an incoming server request in order to produce a response. * If unable to produce the response itself, it may delegate to the provided * request handler to do so. */ public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface; } CC BY-NC 4.0 Justin Yost 9
  9. use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; use Psr\Log\LoggerInterface;

    class LogMiddleware interface MiddlewareInterface { public function __construct(LoggerInterface $logger) { $this->logger = $logger; } public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { // before request $this->logger->info('Request Body {body}', ['body' => $request->getParsedBody()]); // request handled by rest of the stack of middleware and the application $response = $handler->handle($request); // on returning a response return $response; } } CC BY-NC 4.0 Justin Yost 10
  10. $dispatcher = new Dispatcher(new ServerFactory(), new Response()); $dispatcher ->addMiddleware(new AuthMiddleware())

    ->addMiddleware(new LoggingMiddleware()) ->addMiddleware(new CorsMiddleware()) ->run(); CC BY-NC 4.0 Justin Yost 11
  11. class AuthMiddleware interface MiddlewareInterface { public function process(ServerRequestInterface $request, RequestHandlerInterface

    $handler): ResponseInterface { // before request if ($this->notAuthed()) { return $this->throwError(); } // request handled by rest of the stack of middleware and the application $response = $handler->handle($request); // on returning a response return $response; } } CC BY-NC 4.0 Justin Yost 12
  12. class CorsMiddleware interface MiddlewareInterface { public function process(ServerRequestInterface $request, RequestHandlerInterface

    $handler): ResponseInterface { // before request // request handled by rest of the stack of middleware and the application $response = $handler->handle($request); // on returning a response $response = $response->withAddedHeader('Access-Control-Allow-Origin', 'https://myawesome.org'); return $response; } } CC BY-NC 4.0 Justin Yost 13
  13. Framework Support • Laravel (not PSR-15) • Symfony (not PSR-15)

    • CakePHP (PSR-15 full support in Cake 4, currently alpha2) • Slim (PSR-15 full support in Slim4, currently alpha) • Roll your own CC BY-NC 4.0 Justin Yost 14
  14. class LaravelBeforeMiddleware { public function handle($request, Closure $next) { //

    before request // request handled by rest of the stack of middleware and the application return $next($request); } CC BY-NC 4.0 Justin Yost 15
  15. class LaravelAfterMiddleware { public function handle($request, Closure $next) { //

    before request // request handled by rest of the stack of middleware and the application $response = $next($request); // after the response has been crafted return $response } CC BY-NC 4.0 Justin Yost 16
  16. class LaravelTerminableMiddleware { public function terminate($request, $response) { // response

    heading out to the browser and can't be modified } } CC BY-NC 4.0 Justin Yost 17