Erweitertes Ressourcenautorisierungssystem in Laravel. Teil 1. Modell, Steuerung

Einführung


Hallo, liebe Khabrovchans.
Während meiner Arbeit an der API-Plattform habe ich viel Zeit damit verbracht, nach dem richtigen Weg zu suchen, um Benutzeraktionen zu autorisieren. Die Aufgabe wurde wie folgt festgelegt: Schaffung eines ziemlich umfangreichen Systems für Zugriffskontrolle und Aktionen.
Gleichzeitig befinden sich die meisten von ihnen auf einer regulären CRUD, aber andere Controller-Aktionen müssen autorisiert werden.
Daher ist es notwendig, ein einfaches und gleichzeitig effektives und flexibles System zu schaffen. Es gab viele Zapfen, weil ich in diesen Artikeln beschlossen habe, eine etwas vereinfachte Version meiner Arbeit zu demonstrieren.


Ich möchte separat hinzufügen - das Material ist für das Üben von Programmierern konzipiert und für Anfänger schwer zu verstehen. In diesem Artikel werden die Installation des Projekts und die Einstellungen für die Verbindung zur Datenbank nicht geplant. All dies finden Sie leicht im Internet.



Teil 1. Modell, Steuerungen


Die Aufgabe: Es gibt also viele Modelle, deren Anzahl während der Entwicklung des Projekts zunehmen und abnehmen kann.
Aktionen für jede von ihnen sollten durch Rollen autorisiert werden.
Es gibt einfache Aktionen wie CRUD und zusätzliche (z. B. Importieren, Exportieren ).
Es ist notwendig, die Arbeit des Entwicklers (für Ihren Geliebten) so weit wie möglich zu vereinfachen, um ihm zusätzliche Modelle und Methoden vorzustellen.
Der Artikel bietet ein Beispiel für eine Api-Anwendung, aber die Lösung ist nicht nur dafür geeignet.


Modell


Post. ( ) app.
app/Models Posts. ( , -).
. :


    php artisan make:model Models/Post --api --migration
    php artisan migrate

: , . , .



PostController CRUD
Controller.
ModelController Controller , , PostController.
PostControllerimport() 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

, , — :


  1. viewAny view apiResource
  2. , — .

:


. 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
{
    /** @var array 'method' => 'policy'*/
    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
{
    /** @var array 'method' => 'policy'*/
    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 | ..., kann: löschen, posten |
| api / posts / {post} / export | ... \ PostController @ export | ..., kann: export, post |
+ ----------------------- + ------------------------- - + ------------------------------- +



Der nächste Schritt besteht darin, die Link Gate (Gate) <-> -Richtlinie zu konfigurieren. Aber mehr dazu im zweiten Teil .


All Articles