James
James

Reputation: 27

Laravel authorization/policy prevents access for everyone

I found similar title and similar asked question on this website when I was researching to solve the problem. But none of posted answers helped me. This question might be duplicated but I could not solve the problem using existing questions on StackOverflow.
I'm trying to prevent access to users who are not logged in OR who are not member of "School" model!
In "web.php" file I used "middleware("auth")" to prevent access to users who are not logged in.
Now I created a "Policy" named "SchoolPolicy" to prevent access to users who are not member of "Schools" database/model.
When I call "view" method from SchoolPolicy, it prevents access for all authorized and unauthorized users!
I also checked and I realized "School" model returns "null" when I try to catch "user_id" foreign key from "schools" table.
The below piece of code is the way I created "Schools" table using Migration:

Schema::create('schools', function (Blueprint $table) {
  $table->id();
  $table->foreignId('user_id')->constrained();
  $table->string('school_name');
  $table->string('school_address')->nullable();
  $table->string('school_email');
  $table->string('school_phone')->nullable();
  $table->string('url');
  $table->longText('descriptions')->nullable();
  $table->timestamps();
});

This is the route to view any school which is created by any user (URL can be dynamic)

Route::group(['middleware' => 'auth'], function () {
 Route::get('/schools/{url}', [ViewSchool::class, 'index'])->name('yourschool.show');
});

And this is "School" model. I used php artisan make:model School command to create this model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\Auth;

class School extends Model{
  use HasFactory;

  /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
  protected $fillable = [
    'user_id',
    'school_name',
    'school_address',
    'school_email',
    'school_phone',
    'url',
    'descriptions'
  ];
}

In this section I created School Policy. However I used Laravel 8 but I also registered created Policy manually

<?php

namespace App\Policies;

use App\Models\School;
use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;

class SchoolPolicy
{
    use HandlesAuthorization;

    /**
     * Determine whether the user can view any models.
     *
     * @param  \App\Models\User  $user
     * @return mixed
     */
    public function viewAny(User $user)
    {
        //
    }

    /**
     * Determine whether the user can view the model.
     *
     * @param  \App\Models\User  $user
     * @param  \App\Models\School  $school
     * @return mixed
     */
    public function view(User $user, School $school)
    {
        return $user->id == $school->user_id;
    }
}
<?php

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
use App\Models\User;
use App\Models\School;
use App\Policies\SchoolPolicy;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        School::class => SchoolPolicy::class
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();
    }
}
<?php

namespace App\Http\Controllers\Schools;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\School;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;

class ViewSchool extends Controller
{
    public function index (School $school) {

        $this->authorize('view', $school);

        return view('layouts.viewschool');
    }
}

I tried many ways to solve the problem, but none of them properly worked:
public function index (School $school) {

 $this->authorize('view', $school);

}
public function index () {

  $this->authorize('view', School::class);

}
public function index (School $school) {

  dd($school->user_id);

}

I followed all tutorials on YouTube and official Laravel website, but in my examples I gave you, authorization doesn't work properly.
Please help me to solve this problem.
Thank you

Upvotes: 1

Views: 994

Answers (0)

Related Questions