在 Laravel 中间件中访问 $user 变量

Posted

技术标签:

【中文标题】在 Laravel 中间件中访问 $user 变量【英文标题】:Access $user variable inside of Laravel middleware 【发布时间】:2019-08-03 06:33:56 【问题描述】:

我有一个与 Xenforo 集成的 Laravel 应用程序,因此我可以使用 Xenforo 作为应用程序背后的主要用户系统。所有这些都正常工作,但我的下一个挑战是尝试创建中间件,以获取用户的 Xenforo 权限并限制对 Laravel 应用程序上某些页面的访问。

我有一个 $user 变量,我将它传递给我的所有视图,其中包含我需要的所有必要用户数据。我很好奇如何在我的中间件中访问相同的 $user 变量以提取他们的 Xenforo 权限?

我研究了通过我可以在中间件中访问的路由传递变量。但是,我不希望通过 url 传递实际参数来完成任务。

我的 BaseController 包含以下内容并将 $user 变量传递给我的所有视图。

class BaseController extends Controller

    public function __construct()
    
      // Setting up the Xenforo enviornment
      $dir = __DIR__;
      require_once('../public/forum/src/XF.php');
      \XF::start($dir);
      $app = \XF::setupApp('XF\Pub\App');

      // Retrieving the user_id of the current authenticated user
      $session = $app->session();
      $user_id = $session->get('userId');

      // Looking up a users information by their user_id
      $finder = \XF::finder('XF:User');
      $user = $finder->where('user_id', $user_id)->fetchOne();

      // Passing the user to every view
      View::share('user', $user);
    

这里是中间件以及我试图让它运行的方式。我最大的问题是试图访问我最初在上面传递的 $user 变量。

class CheckRole

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    
      // I would like to find a way to access the $user variable here
      if ($user->is_staff == true)
      
          return $next($request);
      
      else
      
          //Restrict access and redirect
      

    

【问题讨论】:

【参考方案1】:

使用默认的 Laravel 用户可以通过 Auth::user() 门面访问。那里的数据通过Authenticate 中间件填充。

在您的情况下,我建议您使用类似的策略,通过实现一个将用户登录的中间件(您现在在控制器中拥有的逻辑),然后实现另一个用于检查角色的中间件。注册两个中间件时要小心,首先执行日志记录的中间件。

您甚至可以自己利用Auth 外观到manually log the user in 并存储您的自定义用户数据like so。

【讨论】:

我应该在上面指定,但我没有“物理地”将用户登录到 Laravel 应用程序。我在控制器中的逻辑基本上只是检查他们是否登录了论坛软件,并通过 $user 变量将他们的用户数据传递给 Laravel。 让论坛和您的应用程序登录状态保持同步是一个想法吗?那么如果用户已经登录论坛,中间件会登录,如果用户没有登录论坛,中间件也会退出? 这是个好主意,但老实说,我与 Laravel 的合作还不够深入,无法深入同步登录状态。我想一个更好的问题是,假设我保持结构不变,是否有更简单的方法来访问我的 $user 变量并保护路由?【参考方案2】:

您可以通过将您的用户数据像这样在控制器中的会话来做到这一点。

$session->put("user_data", $user);

从中间件访问它

$app->session()->get("user_data");

【讨论】:

中间件在控制器之前执行。所以你在控制器中写入会话的数据在中间件中将不可用(除了下一页重新加载) 是的,在您链接的图像中,您可以看到一个请求进来,它首先到达圆圈的外层;中间件。在所有中间件都处理完请求后,调用控制器。 对不起,我应该更清楚一点:中间件既可以在控制器之前,也可以在控制器 see before & after middleware 之后。在 OP 的情况下,中间件将用于保护路由,这是您想要在控制器之前做的事情

以上是关于在 Laravel 中间件中访问 $user 变量的主要内容,如果未能解决你的问题,请参考以下文章

Vue组件中如何使用Laravel数据

如何在 laravel 5.3 中验证没有 auth:api 中间件的用户?

在 Laravel 5.3 的中间件中访问路由 URL 参数

Laravel Sanctum auth:sanctum 路由允许在没有承载令牌的情况下访问

laravel / lumen 访问中间件中的 .env 值

Laravel:我为啥要使用中间件?