Dynamic middleware for laravel 5

While creating packages with multiple tenants for Laravel 5, I had to figure out how to add middleware dynamically from code. Compared to this question on SO, I don't want to touch on Http / Kernel definitions.

During application initialization, I check to see if the requested host name is known in the database and if this host name needs to be redirected to the primary host name or ssl.

Since you do not want to use Http/Kernel as a package, we need to use a service provider.

Requirements:

  • dynamically add middleware without touching Http / Kernel
  • use service provider and response object instead of “hacks”
+8
laravel laravel-5 laravel-routing multi-tenant
source share
1 answer

The solution is to dynamically register middleware in the kernel. First write your middleware, for example:

 <?php namespace HynMe\MultiTenant\Middleware; use App; use Closure; use Illuminate\Contracts\Routing\Middleware; class HostnameMiddleware implements Middleware { public function handle($request, Closure $next) { /* @var \HynMe\MultiTenant\Models\Hostname */ $hostname = App::make('HynMe\Tenant\Hostname'); if(!is_null($redirect = $hostname->redirectActionRequired())) return $redirect; return $next($request); } } 

Now that your service provider uses the following code in the boot() method to add this middleware to the kernel:

 $this->app->make('Illuminate\Contracts\Http\Kernel')->prependMiddleware('HynMe\MultiTenant\Middleware\HostnameMiddleware'); 

To respond to the redirectActionRequired() method in the hostname object:

 /** * Identifies whether a redirect is required for this hostname * @return \Illuminate\Http\RedirectResponse|null */ public function redirectActionRequired() { // force to new hostname if($this->redirect_to) return $this->redirectToHostname->redirectActionRequired(); // @todo also add ssl check once ssl certificates are support if($this->prefer_https && !Request::secure()) return redirect()->secure(Request::path()); // if default hostname is loaded and this is not the default hostname if(Request::getHttpHost() != $this->hostname) return redirect()->away("http://{$this->hostname}/" . (Request::path() == '/' ? null : Request::path())); return null; } 

If you need to dynamically register routeMiddleware, use the following in your service provider:

 $this->app['router']->middleware('shortname', Vendor\Some\Class::class); 

Please add comments if you have questions about this implementation.

+3
source share

All Articles