लारवेल में उन्नत संसाधन प्राधिकरण प्रणाली। भाग 3. पढ़ना / लिखना विशेषताएँ, स्वयं के मॉडल

परिचय


हैलो, प्रिय खाबरोवचन।

आज मैं आपके ध्यान में लारवेल में संसाधनों के साथ कार्यों के उन्नत प्राधिकरण पर लेखों की एक श्रृंखला का अंतिम भाग लाता हूं। इस लेख में क्या चर्चा की जाएगी, यह समझने के लिए, आपको पहले और दूसरे भाग को पढ़ने की आवश्यकता है


इस बार, समस्या बयान थोड़ा बदल गया है: हमारे पास पहले से ही संबंधित नियंत्रकों के तरीकों के प्राधिकरण के माध्यम से संसाधनों के साथ क्रियाओं का प्राधिकरण है। कार्य मॉडल के विशिष्ट क्षेत्रों के संशोधन / देखने को अधिकृत करना है। आपको अपने मॉडलों के लेखक द्वारा संपादन / देखने को अधिकृत करने की क्षमता का भी एहसास करना होगा।


यह सामग्री प्रोग्रामर को अभ्यास करने के लिए है, और एक नौसिखिया डेवलपर को समझना मुश्किल होगा।



भाग 4. विशेषताओं के साथ कार्यों का प्राधिकरण


सैद्धांतिक हिस्सा


इस कार्यक्षमता को कार्यान्वित करने के लिए, मैं लारवेल हसट्रेविजेस, हिड्सएट्यूएंट्स, गार्डसट्यूटेज के अंतर्निहित लक्षणों का उपयोग करने की योजना बना रहा हूंइन लक्षणों के साथ, रूपरेखा बड़े पैमाने पर भरने और विशेषताओं को प्रदर्शित करने को नियंत्रित करती है। मैं विशेषताओं को जबरदस्ती भरने / पढ़ने की क्षमता को छोड़ने की योजना बनाता हूं, क्योंकि यदि मैं सभी पढ़ने / लिखने की क्रियाओं को पूरी तरह से अधिकृत करता हूं, तो यह बहुत संभव है कि हम कार्यक्रम के प्रदर्शन को बाधित करेंगे।


कार्य पूरा करने के लिए, हमें चाहिए:


  • अनधिकृत क्षेत्रों को छुपाने के लिए getHidden (), getV अदृश्य () विधियों को ओवरराइड करें
  • खेतों की अनधिकृत रिकॉर्डिंग से बचाने के लिए isFillable () विधि को ओवरराइड करें
  • authUpdate() .
  • authView() .
  • totallyGuarded() .

— , , . . , . - Banana Monkey Jungle, . / — . .


Laravel :


  • $visible
  • $hidden
  • $guarded
  • $fillable

. $visible . — $guarded . — , .



// , . app/Extensions/Traits, app/Extensions/Traits/GuardedModel. , ( ).

authView()( ) authUpdate()( ), , .

getVisible() getHidden().

, . filterVisibility(), , () .

filterVisibility() $hidden makeHidden(), , userCanViewAttribute($key) . makeVisible()


isFillable($key), , userCanUpdateAttribute($key)


userCanUpdateAttribute($key) userCanViewAttribute($key) . $user->can() spatie/laravel-permission. , , .


GuardedModel


<?php

namespace App\Extensions\Traits;

use App\Models\User;
use Illuminate\Database\Eloquent\Model;

trait GuardedModel
{
    protected function authView(): array
    {
        return [];
    }

    protected function authUpdate(): array
    {
        return [];
    }

    public function getHidden(): array
    {
        $this->filterVisibility();

        return parent::getHidden();
    }

    public function getVisible(): array
    {
        $this->filterVisibility();

        return parent::getVisible();
    }

    public function isFillable($key)
    {
        if (in_array($key, $this->authView())) {
            return $this->userCanUpdateAttribute($key);
        }

        return parent::isFillable($key);
    }

    private function filterVisibility(): void
    {
        $this->makeHidden($this->authView());

        $authVisible = array_filter(
            $this->authView(),
            fn ($attr) => $this->userCanViewAttribute($attr)
        );

        $this->makeVisible($authVisible);
    }

    private function userCanViewAttribute(string $key): bool
    {
        /** @var User $user */
        $user = auth()->user();
        $ability = !empty($user) && $user->can("view-attr-$key-" . static::class);

        return $ability;
    }

    private function userCanUpdateAttribute(string $key): bool
    {
        /** @var User $user */
        $user = auth()->user();
        $ability = !empty($user) && $user->can("update-attr-$key-" . static::class);

        return $ability;
    }

    public function totallyGuarded()
    {
        $guarded = (
            count($this->getFillable()) === 0
            && count($this->authView()) === 0
            && $this->getGuarded() == ['*']
        );

        return  $guarded;
    }
}

totallyGuarded(). Illuminate\Database\Eloquent\MassAssignmentException , . — , .

$user->can(«update-attr-$key-». static::class), . , attr. /.


, authView() authUpdate(). user user_id. user_id, user user_id . . , , $guarded, $hidden, $fillable, .


Posts


<?php

namespace App\Models;

use App\Extensions\Traits\GuardedModel;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use GuardedModel;

    protected $hidden = ['id'];

    protected $guarded = ['created_at', 'updated_at'];

    protected $fillable = ['title', 'description', 'user_id'];

    protected function authView(): array
    {
        return ['user_id', 'user'];
    }

    protected function authUpdate(): array
    {
        return ['user_id'];
    }

    public function user()
    {
        return $this->belongsTo(User::class);
    }
}

5.



. user(), user_id. . , . $user->can('delete-self-'. $this->getModelClass()). , . isOwner(User $user, Model $model). . , , — .


सामान्य मॉडलपॉलिसी नीति


<?php

namespace App\Policies;

use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;
use Illuminate\Database\Eloquent\Model;

abstract class ModelPolicy
{
    use HandlesAuthorization;

    abstract protected function getModelClass(): string;

    public function delete(User $user, Model $model)
    {
        if ($user->can('delete-' . $this->getModelClass())) {
            return true;
        }

        if ($user->can('delete-self-' . $this->getModelClass())) {
            return $this->isOwner($user, $model);
        }

        return false;
    }

    private function isOwner(User $user, Model $model): bool
    {
        if (!empty($user) && method_exists($model, 'user')) {
            return $user->getKey() === $model->getRelation('user')->getKey();
        }

        return false;
    }
}

मैं यह भी ध्यान देता हूं कि रनटाइम में त्रुटियों से बचने के लिए, यह उपयोगकर्ता () विधि या लक्ष्य मॉडल में समान उपलब्धता के लिए एक जांच शुरू करने के लायक है


अभी के लिए इतना ही। आशा है कि यह लेख मददगार रहा है। हमारे पास कार्यों के प्राधिकरण की एक पूरी तरह से और लचीली प्रणाली है। यदि आपके कोई प्रश्न हैं, तो मैं निश्चित रूप से उत्तर दूंगा। और निश्चित रूप से, रचनात्मक टिप्पणियां या सुझाव भी स्वागत योग्य हैं। यदि आप चाहें, तो आप इस प्रशिक्षण परियोजना के कार्यान्वयन को रिपॉजिटरी में अधिक विस्तार से देख सकते हैं


All Articles