Laravel user authorization Gate and Policy

Main points:

  • Laravel has two main ways to implement user authorization: gates and policies.
  • Gates accepts an instance of the currently logged in user as the first parameter. And receive optional parameters, such as the relevant Eloquent model.
  • Using command to generate policy PHP artican make: policy postpolicy -- model = post
    The content generated with the -- model parameter contains CRUD methods
  • Gate is used where the model is not related to resources, and Policy is the opposite.
<?php

namespace App\Policies;

use App\User;
use App\Post;
use Illuminate\Auth\Access\HandlesAuthorization;

class PostPolicy
{
    use HandlesAuthorization;

    /**
     * Determine whether the user can view the post.
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return mixed
     */
    public function view(User $user, Post $post)
    {
        //
    }

    /**
     * Determine whether the user can create posts.
     *
     * @param  \App\User  $user
     * @return mixed
     */
    public function create(User $user)
    {
        //
    }

    /**
     * Determine whether the user can update the post.
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return mixed
     */
    public function update(User $user, Post $post)
    {
        //
    }

    /**
     * Determine whether the user can delete the post.
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return mixed
     */
    public function delete(User $user, Post $post)
    {
        //
    }
}

Operation process:

  1. New Post table and Model file
    php artisan make:migrate create_posts_table
    php artisan make:model Post
    Table information
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->integer('user_id')->unsigned();
            $table->text('body');
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            $table->timestamps();
        });
    }

Fill in data, open UserFactory to add

$factory->define(App\Post::class, function (Faker $faker) {
    return [
        'title' => $faker->sentence,
        'body' => $faker->paragraph,
        'user_id' => factory(\App\User::class)->create()->id,
    ];
});

Post table content


image.png
  1. routes/web.php add
    Route::resource('posts', 'PostsController');

  2. Define Gate
    Open Proviers/AuthServiceProvider.php and modify the boot method

    public function boot()
    {
        $this->registerPolicies();

        // Gates accepts a user instance as the first parameter, and can accept optional parameters, such as the related Eloquent model:
        Gate::define('update-post', function ($user, $post) {
            // return $user->id == $post->user_id;
            return $user->owns($post);
        });
    }

Here, the own method is defined in the User model

    public function owns($post)
    {
        return $post->user_id === $this->id;
    }
  1. In PostsController, only one show method is written
    // Gate demo
    public function show($id)
    {
        $post = Post::findOrFail($id);

        \Auth::loginUsingId(2);

        $this->authorize('update-post', $post);

        if (Gate::denies('update-post', $post)) {
            abort(403, 'sorry');
        }


        // compact('post ') is equivalent to ['post' = > $post]
        return view('posts.view', compact('post'));
        // return $post->title;
    }
  1. Visit / posts/1. It will report 403. This is because we are logged in with user? ID 2.
image.png
  1. If the comment $this - > authorize ('update post ', $post);, it will display:

    image.png

  2. The view determines the Policy. If the user ID of post is the current login user, the edit link will be displayed.

@can('update', $post)
<a href="#> Edit </a>
@endcan

@can and @ cannot are respectively converted into the following statements:

@if (Auth::user()->can('update', $post))
    <! -- current user can update blog -- >
@endif

@unless (Auth::user()->can('update', $post))
    <! -- current user cannot update blog -- >
@endunless

Reference resources: https://d.laravel-china.org/docs/5.5/authorization

Keywords: PHP Laravel

Added by mithril on Sat, 07 Dec 2019 16:04:08 +0200