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:
- 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
routes/web.php add
Route::resource('posts', 'PostsController');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; }
- 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; }
- Visit / posts/1. It will report 403. This is because we are logged in with user? ID 2.
image.png
-
If the comment $this - > authorize ('update post ', $post);, it will display:
image.png 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