У меня есть функция, которая проверяет, есть ли у пользователя разрешение, и возвращает Логический.
Вопрос
Как я проверяю, есть ли у пользователя каждой функции разрешение или нет. Например, в пользовательский контроллер у меня есть 2 функции:
показатель():
public function index () {
if (Auth::user() -> hasPermissionTo('show all users')) {
// continue for API
} else {
// response with error for API
}
}
Я знаю, что есть лучший способ сделать это, потому что я не хочу повторять этот оператор if во всех своих функциях.
Что я пытался сделать:
Я попытался создать вспомогательную функцию, которая проверяет, есть ли у пользователя разрешение, и возвращает ошибку ответа, если у пользователя нет разрешения. И вызывайте его в каждой функции, но это не сработало.
Код вспомогательной функции:
if (!function_exists('userHasPermission')) {
function userHasPermission ($permission) {
$main_permission = 'do everything';
if (!Auth::user() -> hasPermissionTo($main_permission) || !Auth::user() -> hasPermissionTo($permission)) {
$res = trans('api_responses.authorization_failed');
return Response::json([
'message' => $res['message'],
'code' => $res['code']
], $res['code']);
}
}
}
вызов функции индекса
public function index()
{
// PERMISSIONS CHECK
userHasPermission('users show active');
$getUsers = $this -> users -> getAllActive();
return Response::json($getUsers);
}
Но он никогда не возвращает ответ об ошибке, даже если у пользователя нет разрешения, и даже он ввел оператор if в моем помощнике!
@ceejayoz Да, я прочитал это, но моя проблема в том, что я не хочу проверять if else во всех функциях своих контроллеров






Ваша вспомогательная функция возвращает новый ответ, но он возвращает его контроллеру не как HTTP-ответ, поэтому вы можете получить возвращаемое значение следующим образом:
public function index()
{
// PERMISSIONS CHECK
$response = userHasPermission('users show active');
$getUsers = $this -> users -> getAllActive();
return Response::json($getUsers);
}
Итак, вам нужно проверить ответ, имеет ли он значение но при таком подходе вы столкнетесь с той же проблемой, что и ваш первый.
Чтобы решить эту проблему: выбросите исключение из вспомогательной функции вместо того, чтобы возвращать какой-либо ответ.
Лучшее решение должен использовать FormRequest, проверьте этот ссылка, чтобы сделать это, не забудьте проверить раздел «Авторизация запросов формы», в котором указана функция авторизации.
Обновлено:
вам нужно сделать следующее:
создайте новый класс, назовем его «IndexRequest», который наследуется от класса «FormRequest», а затем реализуем метод авторизации.
так что-то вроде этого:
class IndexRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return Auth::user() -> hasPermissionTo('show all users');
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
];
}
}
то в вашем методе:
public function index(IndexRequest $request)
{
$getUsers = $this -> users -> getAllActive();
return Response::json($getUsers);
}
Вам не нужно проверять это вручную, Laravel сделает это за вас, используя функцию «авторизовать» класса IndexRequest.
Проблема в том, что я не хочу делать этот оператор if в каждой функции в каждом контроллере.
Вы должны проверить ссылку, которую я дал в своем ответе! Я думаю, вам нужно добавить "FormRequest", пожалуйста, прочтите документацию!
В Laravel для этого можно использовать гейт.
В вашем файле App \ Providers \ AuthServiceProvider сделайте что-то вроде этого:
public function boot()
{
$this->registerPolicies();
Gate::define('do-everything', function ($user) {
return $user->hasPermission('do-everything');
});
Gate::define('do-one-thing', function ($user) {
return $user->hasPermission('do-one-thing');
});
}
А затем в вашем контроллере:
if (Auth::user()->can('do-everything')) {
// the user can do everything
}
if (Auth::user()->can('do-one-thing')) {
// the user can just do one thing
}
или
if (!Auth::user()->can('do-everything')) {
abort(403);
}
// user has permission to the everything from here on
или в ваших маршрутах / web.php вы можете сделать это:
Route::get('/things', 'ThingController@action')->middleware(['can:do-one-thing']);
или вы можете сгруппировать маршруты следующим образом:
Route::middleware(['can:do-everything'])->group(function () {
Route::get('/things', 'ThingController@index');
Route::get('/other-things', 'OtherThingController@index');
...
}
Вы также можете посмотреть https://laravel.com/docs/5.7/authorization для получения дополнительных идей.
Моя проблема в том, что я не хочу делать этот оператор if else в каждом контроллере, поэтому я ищу лучший метод.
Я уже сделал это, и я могу использовать can('do-everything'), но я буду делать то же самое if для каждой функции контроллера.
@Ahmedessam Вы также можете поместить это в свои маршруты, чтобы он не попал в ваши контроллеры. Смотрите обновление в моем ответе.
Да, промежуточное ПО - лучшее решение для меня ... большое спасибо ... проголосуйте за мой вопрос, это может помочь другим.
Да, промежуточное ПО - лучшее решение для меня ... большое спасибо ... проголосуйте за мой вопрос, это может помочь другим.
Этот способ проверить несколько разрешений, чтобы решить, шо
@php
$patients_menu_item=0;
$users_menu_item=0;
$roles_menu_item=0;
if (Auth::user() -> hasPermissionTo('Patient Add')||Auth::user() -> hasPermissionTo('Patients List')) {
$patients_menu_item=1;
}
if (Auth::user() -> hasPermissionTo('User Add')||Auth::user() -> hasPermissionTo('Users List')) {
$users_menu_item=1;
}
if (Auth::user() -> hasPermissionTo('Role Add')||Auth::user() -> hasPermissionTo('Roles List')) {
$roles_menu_item=1;
}
@endphp
@if ($patients_menu_item == 1)
<li class = "has-sub">
<a>
<i class = "ft-users"></i><span class = "menu-title">Patients</span>
</a>
<ul class = "menu-content">
@can('Patient Add')
<li>
<a href = "{{url('patients/register')}}"
class = "menu-item">Register Patient</a>
</li>
@endcan
@can('Patients List')
<li>
<a href = "{{url('patients/index')}}"
class = "menu-item">{{ trans('website.Show Patients') }}</a>
</li>
@endcan
</ul>
</li>
@endif
Еще один простой способ проверить разрешение внутри контроллера
use Illuminate\Http\Request; //don't forget to include on top
public function index(Request $request)
{
if ($request->user()->canDo('permission you need to check'))
userHasPermission('users show active');
$getUsers = $this -> users -> getAllActive();
return Response::json($getUsers);
}
return Response::json(['Unaurthrorized']);
}
Вы должны прочитать laravel.com/docs/5.7/authorization.