How to check if user has permission to access this function in Laravel
Solution 1
With Laravel you can use a gate for this.
In you App\Providers\AuthServiceProvider
file do something like this:
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');
});
}
And then in your controller:
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
}
or
if (!Auth::user()->can('do-everything')) {
abort(403);
}
// user has permission to the everything from here on
or in your routes/web.php
you could do this:
Route::get('/things', 'ThingController@action')->middleware(['can:do-one-thing']);
or you can group the routes like this:
Route::middleware(['can:do-everything'])->group(function () {
Route::get('/things', 'ThingController@index');
Route::get('/other-things', 'OtherThingController@index');
...
}
You can also look at https://laravel.com/docs/5.7/authorization for more ideas.
Solution 2
Your helper function returns a new response but it returns it to the controller not as HTTP response, so You can get the returned value like this:
public function index()
{
// PERMISSIONS CHECK
$response = userHasPermission('users show active');
$getUsers = $this -> users -> getAllActive();
return Response::json($getUsers);
}
So what you need is to check the response if it has a value but with this approach you are going to have the same problem as your first one.
To solve it: throw exception from the helper function instead of returning some response.
A better solution is to use FormRequest, check this link to do it, be sure to check "Authorizing Form Requests" section which states the authorize function.
EDIT:
what you have to do is the following:
create new class let's call it "IndexRequest" that inherits from "FormRequest" class, then implement authorize method.
so something like this:
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 [
];
}
}
then in your method:
public function index(IndexRequest $request)
{
$getUsers = $this -> users -> getAllActive();
return Response::json($getUsers);
}
you don't have to check it manually, Laravel will do it for you using "authorize" function of IndexRequest class.
Related videos on Youtube
Ahmed essam
Updated on January 24, 2022Comments
-
Ahmed essam over 2 years
I have a function that check if the user has permission or not and it return Boolean.
Question is
How I check in each function user has permission or not. For example in users controller I have 2 functions:
- index(): show all users
- delete($id): delete a single user
index():
public function index () { if(Auth::user() -> hasPermissionTo('show all users')) { // continue for API } else { // response with error for API } }
I know that there is a better way to do that because I don't want to repeat this if statement in all my functions.
What I have tried to do:
I have tried to create a helper function that check if user has permission and return the response error if the user doesn't have permission. And call it in every function but it didn't work.
Helper function code:
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']); } } }
index function call
public function index() { // PERMISSIONS CHECK userHasPermission('users show active'); $getUsers = $this -> users -> getAllActive(); return Response::json($getUsers); }
But it never returns the error response even if the user doesn't have permission and even it entered the if statement in my helper!
-
ceejayoz over 5 yearsYou should read laravel.com/docs/5.7/authorization.
-
Ahmed essam over 5 years@ceejayoz Yea I have read it but my problem is that I don't want to check
if else
in every function in my controllers
-
Ahmed essam over 5 yearsMy problem is that I don't want to make this
if else
statement in every controller that's why I am searching for a better method. -
Ahmed essam over 5 yearsI already made that and I can use
can('do-everything')
but I will do the same if statement every controller function -
Ahmed essam over 5 yearsThe problem is that I don't want to make this if statement in each function in each controller
-
Peter over 5 years@Ahmedessam You can also put this in your routes to keep it out of your controllers. See update in my answer.
-
Ahmed Nour Jamal El-Din over 5 yearsyou must check the link I provided in my answer! I think you have to add "FormRequest", please read the documentation!
-
Ahmed essam over 5 yearsYea Middleware is the best solution for me.. thanks a lot.. please upvote my question it may help others.
-
Ahmed essam over 5 yearsYea Middleware is the best solution for me.. thanks a lot.. please upvote my question it may help others.