【问题标题】:Laravel - Setting a default route prefixLaravel - 设置默认路由前缀
【发布时间】:2020-05-17 03:59:35
【问题描述】:

我想根据用户公司为我的所有路由设置一个默认路由前缀,例如

Route::group(['prefix' => '/{company}'], function() {
    Route::get('/', 'CompaniesController@index')->name('company.index');

});

有什么方法可以通过中间件等设置这个值,这样我就不必对每种方法都做这样的事情,用户只能访问他们自己的公司。

public function index(Company $company)
    {
        if(auth()->user()->company == $company) {
            return $company;
        }
        abort(404);
    }

使用 Laravel 6.x

【问题讨论】:

  • 你是如何使用 Spark 的?您使用的是用户计费还是团队计费?
  • 我没有使用 spark
  • 抱歉,问题看错了。那么答案,我看不出路由组有什么问题?应用前缀,添加一些中间件来检查经过身份验证的用户是否有权访问公司的请求。除非我错过了什么?
  • 您似乎错过了这个问题。问题是“有什么方法可以通过中间件设置这个值”,如果我知道该怎么做,我就不会问这个问题了。
  • 我真的不明白你为什么要在中间件中进行路由注册?中间件用于处理 HTTP 请求和响应;不是应用程序逻辑。使用{company} 参数注册一个动态路由组(如您的示例),然后使用中间件授权用户是否有权访问他们尝试访问的公司。

标签: laravel routes middleware policy


【解决方案1】:

如果您要问的是在 middleware 类中注册路由,那么这实际上是不可能的,因为中间件本身已应用于已注册的路由。


但是,您可以使用route groups 并应用重定向到经过身份验证的用户的“公司”的中间件。

routes.php

<?php

use App\Http\Middleware\RedirectToCompany;

// Use the auth middleware before the RedirectToCompany middleware to make sure users are authenticated

Route::middleware('auth', RedirectToCompany::class)->name('company.')->prefix('/{company}')->group(function () {
    Route::get('/', ....)->name('index');
    //Your routes here
})->where('company', '(google|microsoft|yahoo)'); //Here i supposed that your company is not really bound, you can omit this

注意:如果您的公司有不同的路线,您还可以在显示的路线组内注册多个路线组。

RedirectToCompany.php

<?php

namespace App\Http\Middleware;

use Closure;

public function handle($request, Closure $next)
{
    if ($user->company != $request->route('company')) {
        return redirect()->route('company.index'); //or even abort(404);
    }

    return $next($request); 
}

【讨论】:

    【解决方案2】:

    您不需要任何自定义中间件,您可以使用策略和 laravel 的内置 can 中间件来实现这一点。

    在您的情况下,它将类似于以下内容:

    // app/Policies/CompanyPolicy.php
    class PostPolicy
    {
        public function view(User $user, Company $company)
        {
            return $user->company->getKey() === $company->getKey();
        }
    }
    
    
    // web.php
    Route::group(['prefix' => '/{company}'], function() {
        Route::get('/', 'CompaniesController@index')->name('company.index');
    
    })->middleware('can:view,company');
    
    
    // Controller
    public function index(Company $company)
    {
    
        return 'magic';
    }
    

    有关这方面的更多信息,您可以观看以下文档:
    https://laravel.com/docs/6.x/authorization#creating-policies
    https://laravel.com/docs/6.x/authorization#via-middleware

    【讨论】:

      【解决方案3】:
      1. 使用命令php artisan make:middleware CompanyMiddleware 制作中间件,在Kernel.php 中为其设置名称(我将其命名为“公司”)并处理 公司中间件中的方法必须是这样的:

        public function handle($request, Closure $next) {
          $request->attributes->add(['company' => auth()->user()->company]);
          return $next($request);
        }
        

        在 kernel.php 中:

        'company' => CompanyMiddleware::class,
        
        1. 在路由中应用中间件:

          Route::group(['prefix' => '/{company}', 'middleware' => 'company'], function(){
            Route::get('/', 'CompaniesController@index')->name('company.index');
          });
          
        2. 在为其定义公司中间件的路由方法中获取 $company:

          public function index() {
            $company = request()->company;
          }
          

      希望对你有用。

      【讨论】:

        【解决方案4】:

        您可以像这样在路由级别使用中间件:

        1) 构建您的中间件:

        <?php
        
        namespace App\Http\Middleware;
        
        use App\Models\Company;
        use Closure;
        
        class CheckUserCompany
        {
            /**
             * Handle an incoming request.
             *
             * @param \Illuminate\Http\Request $request
             * @param \Closure $next
             *
             * @return mixed
             */
            public function handle($request, Closure $next)
            {
                if(auth()->user()->company == $request->company) {
                    return $next(;
                }
                 abort(404);
             }
        }
        

        您可能不需要Company 模型,因为您从路由变量中获取公司价值。

        2) 在App\Http\Kernel.php 中注册您的中间件:

        protected $routeMiddleware = [
        'company.check' = \App\Http\Middleware\CheckUserCompany::class
         ];
        

        3) 那么你的路线应该是这样的:

        Route::group(['prefix' => '/{company}', 'middleware' => 'company.check'], function() {
            Route::get('/', 'CompaniesController@index')->name('company.index');
        
        });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-11-14
          • 2015-03-06
          • 2012-03-27
          • 2011-01-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多