【问题标题】:Middleware priority not working in Laravel 5.5中间件优先级在 Laravel 5.5 中不起作用
【发布时间】:2018-09-01 04:21:31
【问题描述】:

我被困在一些我很确定是非常基本的东西上。但不知何故我无法让它工作。

我创建了一个中间件来根据用户的选择设置我的网站的区域设置(他的选择已在数据库中的“区域设置”列下注册)。我所做的是检查用户是否已登录,如果他是我使用他的语言环境,如果不是我默认为英语。

出于某种原因,我的中间件永远不会“看到”用户已登录,并且始终默认为英语。我已将 Auth::check() 的结果输出到日志中,实际上这总是返回 false,即使用户实际上已登录。

我想这与在 Auth 之前执行的中间件有关。我尝试更改内核文件中的优先级,但这仍然不起作用。有什么想法吗?

我的中间件

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class SetLocale {

    public function handle($request, Closure $next) {

      if(Auth::check()) {
        $locale = Auth::user()->locale;
      } else {
        $locale = 'en';
      }
      \App::setLocale($locale);
      return $next($request);
    }
}

我的路由('auth'是默认的auth中间件,'checkProjectPermission:read'检查登录的用户是否有权限访问这个项目)

Route::prefix('client')->middleware(['auth','checkRoomPermission:read'])->group(function() {
    Route::get('{project_id}/checklist', 'ProjectController@accessChecklist')->name('checklist');
}

我的 Kernel.php 文件:

protected $middleware = [
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
    \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
    \App\Http\Middleware\TrimStrings::class,
    \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    \App\Http\Middleware\TrustProxies::class,
    \App\Http\Middleware\SetLocale::class
];

protected $middlewarePriority = [
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    \Illuminate\Auth\Middleware\Authenticate::class,
    \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    \Illuminate\Session\Middleware\AuthenticateSession::class,
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
    \Illuminate\Auth\Middleware\Authorize::class,
    \App\Http\Middleware\SetLocale::class
];

谢谢

【问题讨论】:

  • 请向我们展示路由、分配给该路由的中间件(例如 web/api/auth 等)以及您的Kernel.php 文件中的中间件定义。
  • 在原始帖子中添加了这些 - 虽然忘记准确路线是网络

标签: php laravel laravel-5


【解决方案1】:

问题在于您将SetLocale 添加到您的全局中间件中。 global 中间件没有 start a session,因此您无法访问基于会话的数据 - 例如用户。

如果你看一下 laravel 提供的 web 中间件(为简洁起见清理了)

protected $middlewareGroups = [
    'web' => [
        EncryptCookies::class,
        AddQueuedCookiesToResponse::class,
        CreateFreshApiToken::class,
        StartSession::class,
        ShareErrorsFromSession::class,
        VerifyCsrfToken::class,
        SubstituteBindings::class
    ]
]

您将看到为什么添加到 web 中间件的任何中间件都可以访问 auth 类,因为它注入了 StartSession

如果您想访问基于会话的数据,则需要确保 StartSession 已启动。

不要只是将StartSession 添加到您的全局中间件,否则您会遇到麻烦。而是将其添加到您的 auth 中间件中,并在 StartSession 之后添加 SetLocale

编辑

请注意,如果您使用的是Web Middleware,则还必须将SetLocale 添加到Middleware Group

优先级仅为nsort,它根据middlewarePriority 数组中是否存在中间件,对应用于当前请求的middleware 重新排序。

简化:如果中间件不在路由请求的中间件组中,则中间件优先级没有任何意义。

【讨论】:

  • 感谢 Ohgodwhy - 我认为全局中间件将应用于“web”路由(在“web”中定义的路由之上),但显然情况并非如此。现在像魅力一样工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-31
  • 2021-04-16
  • 1970-01-01
  • 2018-05-26
  • 2018-02-27
  • 1970-01-01
相关资源
最近更新 更多