laravel 5的动态中间件

Luc*_*eos 9 multi-tenant laravel laravel-routing laravel-5

为Laravel 5构建多租户包时,我必须找到如何从代码中动态添加中间件.与SO上的这个问题相比,我不想触及Http/Kernel定义.

在应用程序初始化期间,我检查数据库中是否已知所请求的主机名,以及该主机名是否需要重定向到主主机名或ssl.

因为您不想触摸Http/Kernel包,所以我们需要使用服务提供商.

要求:

  • 动态添加中间件而不触及Http/Kernel
  • 使用服务提供者和响应对象而不是"黑客"

Luc*_*eos 5

解决方案是在内核中动态注册中间件。首先编写您的中间件,例如:

<?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);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,在您的服务提供商中,在boot()方法中使用以下代码将此中间件添加到内核:

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

要回答redirectActionRequired()主机名对象中的方法:

/**
 * 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;
}
Run Code Online (Sandbox Code Playgroud)

如果您需要动态注册routeMiddleware,请在服务提供商中使用以下命令;

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

如果您对此实施有疑问,请添加评论。