Giriş yapmadınız.

#1 27.02.2019 12:58:11

kazim.karagul
Üye
Kayıtlı: 01.11.2014
Mesajlar: 177

Yetkilendirme Sırasında Çok Fazla Sorgu Oluşuyor

Merhaba arkadaşlar,

Aşağıdaki şekilde bir yetkilendirme sistemi kullanıyorum. Sistem modüler şekilde çalışıyor. Her modül aktif olduğunda sidebar'a kendi linklerini ekliyor. Her eklenen link yetki ile kontrol ediliyor. Aynı kodlarla linklerin controller dosyaları da içeride kontrol yapıyor. Yapıda herhangi bir sorun yok. Tüm yetkiler olması gerektiği gibi kontrol ediliyor ama çok fazla sorgu yapılıyor. Aşağıdaki resim admin panelinin index sayfasının sorgu sayısını gösteriyor. Herhangi bir modülün içine girdiğimde sorgular arta da biliyor azala da biliyor. Yine de genel olarak çok fazla sorgu oluşuyor. Vagrant sunucuda bile sayfalar yavaş açılıyor. Gerçek sunucuya almadan sorguları düşürmek istiyorum.

Çözüm için öneri sunabilir misiniz.

@can('general', \Modules\Company\Entities\Company::class)
	@can('index', \Modules\Company\Entities\Company::class)
		<li class="{!! is_active_route('backend.company.index') ? 'active' : '' !!}">Index</li>
	@endcan
	@can('create', \Modules\Company\Entities\Company::class)
		<li class="{!! is_active_route('backend.company.create') ? 'active' : '' !!}">Create</li>
	@endcan
	@can('edit', \Modules\Company\Entities\Company::class)
		<li class="{!! is_active_route('backend.company.index') ? 'active' : '' !!}">Edit</li>
	@endcan
	@can('view', \Modules\Company\Entities\Company::class)
		<li class="{!! is_active_route('backend.company.create') ? 'active' : '' !!}">View</li>
	@endcan
@endcan
namespace Modules\Company\Policies;

use EasySlugger\Slugger;
use Modules\Core\Entities\User;
use Illuminate\Auth\Access\HandlesAuthorization;

class CompanyPolicy
{
    use HandlesAuthorization;

    private $slugger = null;
    private $module = 'company';

    public function __construct()
    {
        $this->slugger = new Slugger();
    }

    private function check_general(User $user){
        if($user->hasPermission($this->module,['company.general'])){
            return true;
        }
        return false;
    }

    public function general(User $user){
        return $this->check_general($user);
    }

    public function index(User $user)
    {
        if($user->hasPermission($this->module,['company.index']) && $this->check_general($user)){
            return true;
        }
        return false;
    }

    public function create(User $user)
    {
        if($user->hasPermission($this->module,['company.create']) && $this->check_general($user)){
            return true;
        }
        return false;
    }

    public function store(User $user)
    {
        if($user->hasPermission($this->module,['company.create']) && $this->check_general($user)){
            return true;
        }
        return false;
    }

    public function view(User $user)
    {
        if($user->hasPermission($this->module,['company.show']) && $this->check_general($user)){
            return true;
        }
        return false;
    }

    public function edit(User $user)
    {
        if($user->hasPermission($this->module,['company.edit']) && $this->check_general($user)){
            return true;
        }
        return false;
    }

    public function update(User $user)
    {
        if($user->hasPermission($this->module,['company.edit']) && $this->check_general($user)){
            return true;
        }
        return false;
    }

    public function delete(User $user)
    {
        if($user->hasPermission($this->module,['company.delete']) && $this->check_general($user)){
            return true;
        }
        return false;
    }
}
public function hasPermission(string $module, array $permissions, $role = null) : bool
{
	$hasModule = Permission::where(['slug' => $module])->first();
	if($hasModule){
		$hasRole = Role::where(['slug' => $role ?: 'admin'])->first();
		if ($hasRole){
			return $hasRole->permissions()
				->wherePivot('role_id', $hasRole->id)
				->wherePivot('permission_id', $hasModule->id)
				->wherePivotIn('permission_slug', $permissions)
				->exists();
		}else{
			return false;
		}
	}else{
		return false;
	}
}

LlN01V.png

Çevrimdışı

#2 27.02.2019 14:19:20

mgsmus
Moderatör
Yer: Mersin
Kayıtlı: 17.08.2013
Mesajlar: 1,536
Website

Yanıt: Yetkilendirme Sırasında Çok Fazla Sorgu Oluşuyor

hasPermission() yöntemi içerisinde cache kullanırsanız sorgular azalacaktır.

hasPermission() içerisinde 3 sorgu yapmışsınız. check_general() yöntemi de onu çağırıyor. 7 yöntem hem hasPermission() hem de check_general() yöntemini çağırıyor, 1 yöntem de sadece check_general() çağırıyor. Bu 45 sorgu demek, bunu bir modül için yapıyorsa 6 modül için 270 sorgu demek.

Çevrimdışı

#3 28.02.2019 09:49:18

ak
Üye
Yer: İstanbul
Kayıtlı: 12.07.2014
Mesajlar: 123

Yanıt: Yetkilendirme Sırasında Çok Fazla Sorgu Oluşuyor

Merhaba,
Laravel Gate kullanılabilir.
https://laravel.com/docs/5.5/authorization#gates

https://github.com/laracasts/laravel-5- … sions-demo linkinden faydalanmıştım(yaklaşık 2 yıl önce)

https://github.com/laracasts/laravel-5-roles-and-permissions-demo/blob/master/app/Providers/AuthServiceProvider.php

getPermissions() cache yapmama rağmen $user->hasPermission($permission) çok bellek kullanıyordu.(70MB~)


Son hali (20MB~)
Model yerine dizi olarak cache yapıldı. hasPermission yerine dizide var mı kontrolü yapıldı.

AuthServiceProvider.php

    protected $userPermissionList;

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        $permissionList = $this->getPermissionList();

        // Dynamically register permissions with Laravel's Gate.
        foreach ($permissionList as $permission_id => $permission_name) {
            Gate::define($permission_name, function ($user) use ($permission_id, $permission_name) {
                if (!isset($this->userPermissionList)) { // Gate dışında auth user a erişmediğim ve bir defa olması için
                    if($user->role_list) {
                        $this->userPermissionList = $this->getUserPermissionList($user);
                    } else $this->userPermissionList = null;
                }

                if(isset($this->userPermissionList[$permission_id])) {
                    return true;
                }
            });
        }
    }

    /**
     * Fetch the collection of site permissions.
     *
     * @return \Illuminate\Database\Eloquent\Collection
     */
    protected function getPermissionList()
    {
        return cache()->tags(['global', 'permissions'])->remember('getPermissionList', 1440, function () {
            return \App\Permission::pluck('name', 'id');
        });
    }

    /**
     * Fetch the collection of user roles permissions.
     *
     * @param  \App\User  $user
     * @return \Illuminate\Database\Eloquent\Collection
     */
    protected function getUserPermissionList($user)
    {
        return cache()->tags(['global', 'permissions', 'roles-firm_'.$user->firm_id])->remember('getUserPermissionList-'.implode('_',$user->role_list), 1440, function () use($user) {
            return \DB::table('permission_role')
            ->whereIn('role_id', $user->role_list)
            ->pluck('permission_id', 'permission_id');
        });
    }

PagePolicy.php

    /**
     * Determine whether the user can create pages.
     *
     * @param  \App\User  $user
     * @return mixed
     */
    public function create(User $user)
    {
        return $user->can('create.pages');
    }

    /**
     * Determine whether the user can update the page.
     *
     * @param  \App\User  $user
     * @param  \App\Models\Page  $page
     * @return mixed
     */
    public function update(User $user, Page $page)
    {
        return $user->can('update.pages') && $user->firm_id === $page->firm_id;
    }

Gate/Policy kullanımı ile ilgili Laravel dökümantasyonda detaylı bilgi bulunmaktadır.

İyi çalışmalar..

Çevrimdışı

#4 28.02.2019 15:31:59

sineld
Yönetici
Yer: Bursa
Kayıtlı: 26.12.2012
Mesajlar: 1,439
Website

Yanıt: Yetkilendirme Sırasında Çok Fazla Sorgu Oluşuyor

Bu tür durumlarda doğrusu işi Gate aracılığı ile Laravel container'a yüklemek ve iznin varlığını bu container içinden sorgulamaktır.

Gate::define

ile yaptığınız işlem tam olarak budur. Uygulama içinde can / cannot benzeri sorgulamalar yaptığınızda denetim Gate üzerinden yapıldığından her seferinde SQL sorgusu yapılmaz.

Çevrimdışı

Forum alt kısmı