We continue to move forward with Laravel and our blog. Today we are going to explain what the policies are and we will apply them to our project.
Policies are classes that allow us to handle the authorizations. That is, they allow us to restrict user access to certain parts of the project easily.
Create the policy:
1 |
php artisan make:policy PostPolicy |
Now we have to register the policy, open the file app\Providers\AuthServiceProvider.php and add the following line to the policies array:
1 2 3 |
... 'App\Post' => 'App\Policies\PostPolicy', ... |
As we can see, every policy has a related model.
Once registered, we have to create the restrictions to use them from the controller. Open the policy file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php namespace App\Policies; use Illuminate\Auth\Access\HandlesAuthorization; use Illuminate\Support\Facades\Auth; use App\User; use App\Post; class PostPolicy { use HandlesAuthorization; public function update(User $user, Post $post) { return $user->id === $post->user_id; } public function delete(User $user, Post $post) { return $user->id === $post->user_id; } } |
The added methods do the same, check if the logged in user is the same as the creator. One will be for editing and the other one for deletion.
We eliminated almost all the middlewares, because with the policies that we will add now, they aren’t necessary. The controller will look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Post; use App\Http\Requests\PostRequest; use Illuminate\Support\Facades\Auth; class PostsController extends Controller { public function __construct() { $this->middleware('auth')->only('store'); } public function show($id) { $post = Post::findOrFail($id); return view('post', ['post' => $post]); } public function index() { $posts = Post::all(); return view('posts', ['posts' => $posts]); } public function store(PostRequest $request) { Post::create([ 'title' => $request->title, 'body' => $request->body, 'user_id' => Auth::id() ]); return redirect('posts'); } public function edit(Request $request) { $post = Post::findOrFail($request->id); $this->authorize('update', $post); return view('post_edit', ['post' => $post]); } public function update(PostRequest $request) { $post = Post::findOrFail($request->id); $this->authorize('update', $post); $post->update([ 'title' => $request->title, 'body' => $request->body ]); return redirect('posts'); } public function destroy(Request $request) { $post = Post::findOrFail($request->id); $this->authorize('delete', $post); $post->delete(); return redirect('posts'); } } |
Now we only need to create the view of the error that returns us when the condition of the policy isn’t true. Create a file called 403.blade.php in resources/views/errors :
1 |
<p>Unauthorized</p> |
I put that content, but you can put whatever you what.
-
Policies: https://laravel.com/docs/5.4/authorization