introduction
Bonjour, cher Khabrovchans.
Au cours de mon travail sur la plate-forme api, j'ai passé beaucoup de temps à chercher la bonne façon d'autoriser les actions des utilisateurs. La tâche a été définie comme suit - créer un système assez étendu de contrôle d'accès et d'actions.
Dans le même temps, la plupart d'entre eux sont sur un CRUD régulier, mais d'autres actions du contrôleur devront être autorisées.
Il est donc nécessaire de créer un système simple et à la fois efficace et flexible. Il y avait beaucoup de cônes, car dans ces articles, j'ai décidé de démontrer une version quelque peu simplifiée de ce que j'ai fait.
Je voudrais ajouter séparément - le matériel est conçu pour les programmeurs pratiquants et sera difficile à comprendre pour un débutant. Cet article ne planifiera pas l'installation du projet et les paramètres de connexion à la base de données. Tout cela, vous pouvez facilement le trouver sur Internet.
Partie 1. Modèle, contrôleurs
Donc, la tâche: Il existe de nombreux modèles, dont le nombre peut augmenter et diminuer au cours du développement du projet.
Les actions sur chacun d'entre eux doivent être autorisées par les rôles.
Il existe des actions simples, telles que CRUD, et d'autres (par exemple, importation, exportation ).
Il est nécessaire de simplifier le travail du développeur (à votre bien-aimé) autant que possible pour leur introduire des modèles et des méthodes supplémentaires.
L'article fournit un exemple pour une application Api, mais la solution ne convient pas seulement à cela.
Modèle
Post. ( ) app.
app/Models Posts. ( , -).
. :
php artisan make:model Models/Post --api --migration
php artisan migrate
: , . , .
PostController CRUD
Controller.
ModelController Controller , , PostController.
PostController — import() export(Post $post).
, .
Laravel Illuminate\Foundation\Auth\Access\AuthorizesRequests.
App\Http\Controllers\Controller ModelController. Controller , .
authorizeResource($model).
, (Middleware) .
:
can:viewAny,App\Models\Post
can:view,post
can:update,post
, , — :
- viewAny view apiResource
- , — .
:
. resourceAbilityMap() .
<?php
protected function resourceAbilityMap()
{
return [
'index' => 'viewAny',
'show' => 'view',
'create' => 'create',
'store' => 'create',
'edit' => 'update',
'update' => 'update',
'destroy' => 'delete',
];
}
. Laravel . , . index() , show(Post $post) . resourceMethodsWithoutModels()
<?php
protected function resourceMethodsWithoutModels()
{
return ['index', 'create', 'store'];
}
(ModelController)
app/Http/Controllers ModelController. :
- $guardedMethods « » => « ».
(Policy) , , (Gate). .
- $methodsWithoutModels .
- getModelClass() .
.
- authorizeResource($this->getModelClass()) . ( (Route), )
- resourceAbilityMap() resourceMethodsWithoutModels() , , .
<?php
namespace App\Http\Controllers;
abstract class ModelController extends Controller
{
protected $guardedMethods = [];
protected $methodsWithoutModels = [];
protected abstract function getModelClass(): string;
public function __construct()
{
$this->authorizeResource($this->getModelClass());
}
protected function resourceAbilityMap()
{
$base = parent::resourceAbilityMap();
return array_merge($base, $this->guardedMethods);
}
protected function resourceMethodsWithoutModels()
{
$base = parent::resourceMethodsWithoutModels();
return array_merge($base, $this->methodsWithoutModels);
}
}
(PostController)
:
- getModelClass() .
- $methodsWithoutModels « » => « » . . , =. , , .
- $methodsWithoutModels , . import
- — , . — .
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends ModelController
{
protected $guardedMethods = [
'export' => 'export',
'import' => 'import',
];
protected $methodsWithoutModels = ['import'];
protected function getModelClass(): string
{
return Post::class;
}
public function index()
{ }
public function store(Request $request)
{ }
public function show(Post $post)
{ }
public function update(Request $request, Post $post)
{ }
public function destroy(Post $post)
{ }
public function import()
{ }
public function export(Post $post)
{ }
}
(Routes)
.
'routes/api.php' ( 'routes/web.php', ) .
, , .
— ( ) , Route::apiResource('posts', 'PostController'). Laravel. .
— 'auth:api'. , .
<?php
use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;
Route::group(['middleware' => ['auth:api']], static function () {
Route::post('posts/import', 'PostController@import')->name('posts.import');
Route::get('posts/{post}/export', 'PostController@export')->name('posts.export');
Route::apiResource('posts', 'PostController');
});
. :
php artisan route:list
— ( )
+-----------------------+---------------------------+-------------------------------+
|URI |Action |Middleware |
+-----------------------+---------------------------+-------------------------------+
|api/posts |...\PostController@index |...,can:viewAny,App\Models\Post|
|api/posts |...\PostController@store |...,can:create,App\Models\Post |
|api/posts/import |...\PostController@import |...,can:import,App\Models\Post |
|api/posts/{post} |...\PostController@show |...,can:view,post |
|api/posts/{post} |...\PostController@update |...,can:update,post |
| api / posts / {post} | ... \ PostController @ destroy | ..., peut: supprimer, publier |
| api / posts / {post} / export | ... \ PostController @ export | ..., peut: exporter, publier |
+ ----------------------- + ------------------------- - + ------------------------------- +
L'étape suivante consiste à configurer la stratégie Link Gate (Gate) <->. Mais plus à ce sujet dans la deuxième partie .