用于Laravel 5的动态中间件 [英] Dynamic middleware for laravel 5
问题描述
为Laravel 5构建多租户包时,我不得不找出如何添加中间件从代码中动态生成.与上的问题相比所以我不想碰到Http/Kernel定义.
While building multi-tenancy packages for Laravel 5 I had to find out how to add middleware dynamically from code. In comparison to this question on SO I do not want to touch the Http/Kernel definitions.
在应用程序初始化期间,我检查数据库中是否知道所请求的主机名以及该主机名是否需要重定向到主主机名或ssl.
During application initialization I check whether the requested hostname is known in the database and whether this hostname requires a redirect to a primary hostname or ssl.
由于您不想将Http/Kernel
作为包装使用,因此我们需要使用服务提供商.
Because you don't want to touch the Http/Kernel
as a package, we need to use the service provider.
要求:
- 动态添加中间件,而无需触及Http/Kernel
- 使用服务提供者和响应对象而不是"hacks"
推荐答案
解决方案是在内核中动态注册中间件.首先编写您的中间件,例如:
The solution is to dynamically register the middleware in the kernel. First write your middleware, for instance:
<?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);
}
}
现在在您的服务提供商中,在boot()
方法中使用以下代码添加此代码中间件到内核:
Now in your service provider use 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');
要回答redirectActionRequired()
方法在主机名对象中的作用,
To answer what redirectActionRequired()
method does 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;
}
如果您需要动态注册routeMiddleware,请在服务提供商中使用以下内容;
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.
这篇关于用于Laravel 5的动态中间件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!