Laravel - 设置默认路由前缀
Laravel - Setting a default route prefix
我想根据用户公司为我的所有路由设置默认路由前缀,例如
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
你可以像这样在路由级别使用中间件:
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');
});
用命令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,
在路由中应用中间件:
Route::group(['prefix' => '/{company}', 'middleware' => 'company'], function(){
Route::get('/', 'CompaniesController@index')->name('company.index');
});
在为其定义公司中间件的路由方法中获取 $company:
public function index() {
$company = request()->company;
}
希望对你有用。
为此您不需要任何自定义中间件,您可以使用策略和 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
如果你问的是在 中间件 class 中注册路由,那是不可能的,因为中间件本身是应用在已经注册的路线。
但是,您可以使用 route groups 并应用重定向到经过身份验证的用户的 "company" 的中间件。
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
Note: You are also able to register multiple route groups inside of the presented route group if your companies have different routes.
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);
}
我想根据用户公司为我的所有路由设置默认路由前缀,例如
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
你可以像这样在路由级别使用中间件:
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');
});
用命令
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,
在路由中应用中间件:
Route::group(['prefix' => '/{company}', 'middleware' => 'company'], function(){ Route::get('/', 'CompaniesController@index')->name('company.index'); });
在为其定义公司中间件的路由方法中获取 $company:
public function index() { $company = request()->company; }
希望对你有用。
为此您不需要任何自定义中间件,您可以使用策略和 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
如果你问的是在 中间件 class 中注册路由,那是不可能的,因为中间件本身是应用在已经注册的路线。
但是,您可以使用 route groups 并应用重定向到经过身份验证的用户的 "company" 的中间件。
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
Note: You are also able to register multiple route groups inside of the presented route group if your companies have different routes.
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);
}