我在一个名为 rolMiddleware 的中间件中获得了这个句柄:
public function handle($request, Closure $next, $roles)
{
//dd($request->user());
foreach ($roles as $rol) {
if ($request->user()->getTipoUsuario($request->user()->tipo_usuario_id)->getNombreTipoUsuario() == $rol) {
return $next($request);
}
}
abort(403, "¡No hay autorizacion!");
}
但是 $roles 是一个数组,这是我使用中间件的路线:
Route::get('/mid', ['middleware' => 'roles:super admin', function () {
return "done";
}]);
给我的错误是:
ErrorException in RolMiddleware.php line 22:
Invalid argument supplied for foreach()
您可能会认为我不需要数组,因为我只在超级管理员中使用它,对于该路线我只需要超级管理员,但会有可以用于超级管理员和区域管理员的路线。
在 laravel 中,您可以使用逗号
,
分隔要传递给中间件的参数,如下所示:
Route::get('/mid', ['middleware' => 'roles:super,admin', function () {
// ^ note this
return "done";
}]);
请注意,这不会将参数作为数组发送,因此您无法循环
$roles
,除非您将传递的参数用作省略号参数,如下所示:
public function handle($request, Closure $next, ...$roles)
相反,您需要为每个角色使用一个参数:
public function handle($request, Closure $next, $role1, $role2) // .... and so on
路线:
Route::get('/access', ['middleware' => 'hasroles:super,admin', function () {
}]);
传递一个参数来检查用户是否在我的中创建了权限 原因
Route::middleware('admin')->namespace('Admin')->prefix('admin')->group(function(){
Route::get('/home', 'MainController@getIndex')->name('admin.index')->middleware("hasrole:create");
中间件:
1.使用参数
public function handle($request, Closure $next, $parm1, $parm2){}
2.使用var-arg
public function handle($request, Closure $next, $parm1, $parm2){}
public function handle($request, Closure $next, ...$parm1){}
双向中间件使用
1:注册routeMiddleware
// Within App\Http\Kernel Class...
protected $routeMiddleware = [
'hasrole' => \Illuminate\Auth\Middleware\HasRole::class,
使用:
Route::get('admin/profile', function () {
})->middleware('hasrole');
2:未在routeMiddleware中注册
使用:
use App\Http\Middleware\HasRole;
Route::get('admin/profile', function () {
//
})->middleware(HasRole::class);
以字符串形式发送参数,如 as
Route::prefix('panel')->middleware('auth:admin|editor')->group(function (){
Route::get('/', [SiteController::class, 'index'])->name('site.index');
}
在中间件中编程以将此字符串感知为数组
if (in_array(Auth::user()->rule, explode('|', $access))) {
return $next($request);
} else {
return redirect()->route('site.denied');
}
我不太明白你的功能是做什么的,但你可以尝试这样的事情:
public function handle($request, Closure $next, $roles)
{
if(is_array($roles)){
//dd($request->user());
foreach ($roles as $rol) {
if ($request->user()->getTipoUsuario($request->user()->tipo_usuario_id)->getNombreTipoUsuario() == $rol) {
return $next($request);
}
}
}else{
if($request->user()->getTipoUsuario($request->user()->tipo_usuario_id)->getNombreTipoUsuario() == $roles)
return $next($request);
}
abort(403, "¡No hay autorizacion!");
}
您可以使用
explode
中的 middleware
函数将 string
转换为 array
。
控制器:
public function __construct()
{
$this->middleware('RoleCheck:admin|user')->except(['index', 'show']);
}
中间件:
public function handle(Request $request, Closure $next, $roles)
{
$user = Auth::user();
$roles = explode("|", $roles); // convert $roles to array
foreach ($roles as $role) {
if ($user->hasRole($role))
return $next($request);
}
return redirect('login');
}
中间件文件末尾应该始终有
return $next($request);
...其中一些示例未能做到这一点。
您的路线如下(web.php 文件):
Route::middleware('CheckRole:super-admin')->group(function () {
//routes here
});
您的中间件将是:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class CheckRole
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
*/
public function handle(Request $request, Closure $next, ...$roles): Response
{
if ($request->user()) {
$userRole = Auth::user()->role->value('name');
if (! in_array($userRole, $roles)) {
abort(403, 'Your account permissions do not allow access to the requested page');
}
}
return $next($request);
}
}
这假设您只有 1 个用户的 1 个角色。如果您为 1 个用户拥有多个角色,那么您的中间件代码中将进行不同的检查