Laravel-设置默认路由前缀

时间:2020-01-31 13:10:06

标签: laravel routes middleware policy

我想根据用户公司为我的所有路由设置默认路由前缀。

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

4 个答案:

答案 0 :(得分:1)

您可以在路由级别使用中间件,如下所示:

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');

});

答案 1 :(得分:1)

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

    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;
      }
      

我希望对您有用。

答案 2 :(得分:1)

您不需要任何自定义中间件,可以使用策略和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 :(得分:0)

如果您要在 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); 
}