Continuamos avanzando con Laravel y nuestro blog. Hoy vamos a explicar qué son las policies y las aplicaremos a nuestro proyecto.
Las policies son clases que nos permiten manejar las autorizaciones. Es decir, nos permiten restringir el acceso a usuarios a ciertas partes del proyecto fácilmente.
Creamos la policy:
1 |
php artisan make:policy PostPolicy |
Ahora tenemos que registrar la policy, para eso abrimos el archivo app\Providers\AuthServiceProvider.php y en el array de policies añadimos la siguiente línea:
1 2 3 |
... 'App\Post' => 'App\Policies\PostPolicy', ... |
Como podemos ver cada policy tiene un modelo relacionado.
Una vez registrada tenemos que crear las restricciones para utilizarlas desde el controlador, aunque también se pueden utilizar desde las vistas, middleware y otros. Abrimos la policy:
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; } } |
Los métodos añadidos hacen lo mismo, comprueban si el usuario logueado es el mismo que el creador. Uno será para la edición y el otro para la eliminación.
Eliminamos casi todos los middlewares, porque con las policies que añadiremos ahora, el problema que solventaban, ya se resuelve. El controlador quedará así:
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'); } } |
Ahora solamente nos falta crear la vista del error que nos retorna cuando no se cumple la condición de la policy. Creamos un archivo llamado 403.blade.php en resources/views/errors :
1 |
<p>Unauthorized</p> |
Yo le he puesto ese contenido, pero tú puedes poner lo que quieras y darle el diseño que quieras también.
-