نظام تخويل الموارد المتقدم في Laravel. الجزء 1. نموذج ، وحدة تحكم

المقدمة


مرحبا عزيزي خابروفشان.
في أثناء عملي على منصة api ، قضيت الكثير من الوقت في البحث عن الطريقة الصحيحة لتفويض إجراءات المستخدم. تم تعيين المهمة على النحو التالي - لإنشاء نظام واسع النطاق إلى حد ما لمراقبة الدخول والإجراءات.
في نفس الوقت ، معظمهم على CRUD العادية ، ولكن يجب أن يتم ترخيص إجراءات التحكم الأخرى.
لذلك من الضروري إنشاء نظام بسيط وفعال ومرن في نفس الوقت. كان هناك الكثير من المخاريط ، لأنني قررت في هذه المقالات عرض نسخة مبسطة إلى حد ما لما فعلته.


أود أن أضيف بشكل منفصل - تم تصميم المواد لممارسة المبرمجين ، وسيكون من الصعب على المبتدئ فهمها. لن تقوم هذه المقالة بجدولة تثبيت المشروع وإعدادات الاتصال بقاعدة البيانات. كل هذا يمكنك العثور عليه بسهولة على الإنترنت.



الجزء 1. نموذج ، وحدات تحكم


لذلك ، المهمة: هناك العديد من النماذج ، التي يمكن أن يزيد عددها وينخفض ​​أثناء تطوير المشروع.
الإجراءات على كل منهم يجب أن تأذن به الأدوار.
هناك إجراءات بسيطة ، مثل CRUD ، وإجراءات إضافية (على سبيل المثال ، الاستيراد والتصدير ).
من الضروري تبسيط عمل المطور (لمن تحب) لعمل نماذج وأساليب إضافية لهم.
تقدم المقالة مثالًا لتطبيق Api ، ولكن الحل مناسب ليس فقط لذلك.


نموذج


للتوضيح ، قم بإنشاء نموذج مشاركة . أفضل الابتعاد عن الممارسة غير المناسبة (في حالتنا) لتخزين النماذج في جذر مجلد التطبيق.
لذلك ، أقوم بإنشاء مجلد التطبيق / النماذج وفيه نموذج المشاركات. (من المفترض أنه سيكون هناك الكثير من النماذج ، وإلا لماذا كل هذه الضجة).
نقوم بإنشاء جدول للنموذج. للقيام بذلك ، قم بتنفيذ الأوامر التالية في وحدة التحكم:


    حرفي php جعل نموذج: نموذج / بعد - آبي - الهجرة
    يهاجر الحرفي فب

ونتيجة لذلك ، نحصل على المعايير القياسية: النموذج والهجرة والتحكم. لا يجب أن نتطرق إلى النموذج والهجرة ، لأنني لن أغيرهما في إطار هذه المقالة.


مراقب


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 @ destruction | ...، can: delete، post |
| api / posts / {post} / export | ... \ PostController @ export | ...، can: export، post |
+ ----------------------- + ------------------------- - + ------------------------------- +



الخطوة التالية هي تكوين سياسة بوابة البوابة (البوابة) <->. ولكن المزيد عن ذلك في الجزء الثاني .


All Articles