Home > Software engineering >  Laravel 7: How can I restrict URL by user?
Laravel 7: How can I restrict URL by user?

Time:06-29

I'm a newbie who is learning Laravel 7. I have developed a small web application with Laravel 7. But today I noticed one problem. That all the URLs are global, means all users can access all the URLs of my website. Suppose User A created data and it shows in a table where the edit and delete buttons exist with every row. The edit URL is like: localhost/records/edit/5. The problem is, that other logged-in users can access this edit page also. Like this, all the URLs are accessible by any logged-in users which is very bad. I hope you understand what I'm saying. I have almost 250 web routes. Is there any easy way to restrict the routes? User can access their own data only. How can I do that? Thanks

CodePudding user response:

  1. store user_id when new record added > Add created_by field in user_table DB
  2. when user run URL > get logged-in user user_id from session and check in DB for their record > if record not found then redirect to home page with message otherwise continue.

CodePudding user response:

You'll have to register policies and ensure users cannot access parts of the website without the correct authorization.

See the docs on how to write policies and implement them.

Sample code:

Policy:

class RecordPolicy 
{
    public function delete(User $user, Record $record)
    {
        return $user->id === $record->user_id;
    }
}

Controller

class RecordController
{
    public function destroy(Record $record)
    {
        // Authorize the delete action before actually deleting the record
        $this->authorize('delete', $record);

        $record->delete();
    }
}

Records index

@foreach($records as $record)
    <div> 
        {{ $record->name }}

        {{-- Only show delete button if the authorized user can actually delete the record --}}
        @can('delete', $record)
            <form action="{{ route('records.destroy', compact('record') }}" method="POST">
                @csrf
                @method('DELETE')
                <button type="submit">Delete record</button>
            </form>
        @endcan
    </div>
@endforeach

CodePudding user response:

If i understand you correctly you want to restrict routes to specific user.

  1. Create a roles table
Columns (id, name) 

(1 = Super Admin, 2 = Admin, 3 = User)
  1. Assign Roles To User While Creating new User i.e add role_id to users table.
$user = User::create([
  'name' => 'First Admin',
  'email' => '[email protected]',
  'password' => Hash::make('Admin@1234'),
  'role_id'  => 2 // For admin role
]);
  1. Then Create Middlewares for each role and restrict routes for specific users.

Admin Middleware: AdminMiddleware.php

public function handle(Request $request, Closure $next)
    {
        $allowedRoles = [2];
        if (!in_array(Auth::user()->role_id, $allowedRoles))
            {
                return redirect()->back()->with('error',__('Sorry, you are not authorized to access that location.'));
            }
        return $next($request);
    }

In Kernel.php

'admin' => \App\Http\Middleware\AdminMiddleware::class,
Route::group(['middleware' => 'admin'], function(){
   // All admin Routes
});

You Can also Use Spatie package for this.

https://spatie.be/docs/laravel-permission/v5/basic-usage/middleware

Just Check If Role is allowed to use that route:

Route::group(['middleware' => ['auth', 'role:admin']], function () {
    // All routes available for admin
});
  • Related