Abhishek Shah
Abhishek Shah

Reputation: 145

Laravel preventing user from accessing other users resource **url

I am passing a specific resource in the url, for ex. https://www.example.com/{companyID}

And in the controller I can access the resource by

public function index($companyID)
{
    // Code Here
}

I need to block users from changing the url and accessing other companyIDs from the system. Currently its open and is a security risk. I checked out Laravel Gate and Policy's but fail to see how this could be implemented for my case.

What I am really looking for is something in the AuthServiceProvider boot method that can check if the user really is the owner of the resource before continuing with the code.

Any help?

Upvotes: 2

Views: 5857

Answers (2)

Matthias S
Matthias S

Reputation: 3553

As mentioned before, you can do that by creating a Middleware that checks if your resource should be available to the logged in user.

See some details about middleware here

First, create a Middleware via php artisan, like this

php artisan make:middleware AuthResource

Next, add it to your App\Http\Kernel.php

protected $routeMiddleware = [
    ...
    'AuthResource' => \App\Http\Middleware\AuthResource::class,
];

In your routes, you can now do the following:

Route::get('{companyID}', ['uses' => CompanyController@index, 'middleware' => 'AuthResource']);

That way, your AuthResource middleware is used whenenver the route is called. In your App\Http\Middleware\AuthResource.php you have to change the code from

public function handle($request, Closure $next)
{
    return $next($request);
}

to something that checks if the resource is available to the currently logged in user. I assume that your companies table has a field user_id, which links the Company to a User. If your data structure is different, you need to change the code accordingly.

public function handle($request, Closure $next)
{
    if ($request->route('companyID')) {
        $company = Company::find($request->route('companyID'));
        if ($company && $company->user_id != auth()->user()->id) {
            return redirect('/');
        }
    }

    return $next($request);
}

That way we check if the a route parameter with the name companyID exists, and if it does we check if it is available to the currently logged in user. If no companyID parameter is available, the page can be loaded without any restrictions.

That way you can copy/paste the code within the middleware for any parameters so that the middleware does work for multiple resources (not only companies).

Upvotes: 7

dilusha_dasanayaka
dilusha_dasanayaka

Reputation: 1441

This is can be done easily by middleware. But I’ll do this in more understandable way. I assume that your user has one to one relationship with company. So first create the relationship, In your User model,

Public function company() {
    return $this->hasOne(‘App\Company’);
}

Company model

Public function user(){
   return $this->belongsTo(‘App\User’);
}

So, now make Authenticate by running php artisan make:auth . more details on Authenticate

And now in your controller,

public function index($companyID)
{
    $current_user = Auth::user();
    $user_company = $current_user->company; // get the current user's company details
    If($companyID == $user_company->id){
        // do something
    }
}

Upvotes: 1

Related Questions