亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

首頁 php教程 PHP視頻 Laravel5權(quán)限管理方法詳解

Laravel5權(quán)限管理方法詳解

Dec 23, 2016 pm 05:27 PM

本文實(shí)例講述了Laravel5權(quán)限管理的實(shí)作方法。分享給大家參考,具體如下:

關(guān)於權(quán)限管理的思考

最近用laravel設(shè)計(jì)後臺(tái),後臺(tái)需要有個(gè)權(quán)限管理。權(quán)限管理實(shí)質(zhì)上分為兩個(gè)部分,首先是認(rèn)證,然後是權(quán)限。認(rèn)證部分非常好做,就是管理員登錄,記錄session。這個(gè)laravel中也有自備Auth來實(shí)現(xiàn)這個(gè)。最麻煩就是權(quán)限認(rèn)證。

權(quán)限認(rèn)證本質(zhì)上就是誰有權(quán)限管理什麼東西。這裡有兩個(gè)方面的維度,誰,就是用戶維度,在用戶維度,權(quán)限管理的粒度可以是用戶一個(gè)人,也可以是將用戶分組,如果將用戶分組,則涉及到的邏輯是一個(gè)用戶可以在多個(gè)組裡面嗎?在另一方面,管理什麼東西,這個(gè)東西是物的維度,一個(gè)頁面是一個(gè)東西,一個(gè)頁面上的一個(gè)元素也是一個(gè)東西,或者往大了說,一個(gè)功能是一個(gè)東西。所以做權(quán)限管理最重要的是確認(rèn)這兩個(gè)維度的粒度。這已經(jīng)不是技術(shù)的事情了,這個(gè)是需要需求討論的了。

基於上面的思考,我這次想做的權(quán)限管理,在使用者維度,是基於個(gè)人的。就是每個(gè)人的權(quán)限不一樣。在東西的維度,我設(shè)定路由為最小的單位,也就是可以為單一路由設(shè)定權(quán)限管理。

下面的思考就是使用什麼來標(biāo)記權(quán)限,可以使用位,也可以使用字符,也可以使用整型。後來我選擇了字符,基於兩點(diǎn)考慮:1 字符淺顯易懂,在數(shù)據(jù)庫(kù)中查找也比較方便2 我沒有按照某個(gè)權(quán)限查找有這個(gè)權(quán)限的人的需求,即沒有反查需求,使用位,整型等都意義不大。

接下來考慮如何和laravel結(jié)合,既然要為每個(gè)路由設(shè)定存取權(quán)限,那麼我當(dāng)然希望能在laravel的route.php路由管理中配置。最好就是在Route::get的時(shí)候有個(gè)參數(shù)能設(shè)定permission。這樣做的好處是權(quán)限設(shè)定簡(jiǎn)易了。在決定路由的時(shí)候,就順手寫了權(quán)限控制。壞處呢,也很明顯,laravel路由的三種方式只能寫一種了。就是Route::(method)這樣的方式了。

基本上決定好了就開乾。

路由設(shè)計(jì)

基本的路由是這樣的

Route::post('/admin/validate', ['uses' => 'AdminController@postValidate', 'permissions'=>['admin.validate', 'admin.index']]);

這裡在基本的製定路由action之後設(shè)定了一個(gè)permissions的屬性,這個(gè)屬性設(shè)計(jì)成數(shù)組,因?yàn)槔缫粋€(gè)post請(qǐng)求,它可能在某個(gè)頁面會(huì)觸發(fā),也可能在另一個(gè)頁面觸發(fā),那麼這個(gè)post請(qǐng)求就需要同時(shí)擁有兩個(gè)頁面路由的權(quán)限。

這裡使用admin.validate的權(quán)限控制,這樣,可以將權(quán)限分組,admin都是關(guān)於admin相關(guān)的分組,在資料庫(kù)中,我就會(huì)儲(chǔ)存一個(gè)二維數(shù)組,[admin] => ['validate', 'index']; 儲(chǔ)存成二維數(shù)組而不是一維的好處呢,一般後臺(tái)展示是有兩個(gè)維度的,一個(gè)是頭部的tab欄,一個(gè)是左邊的nav欄,就是說這個(gè)二維的數(shù)組和後臺(tái)的tab,nav欄是一一對(duì)應(yīng)的。

中間件設(shè)計(jì)

好了,下面我們就掛上中間件,並且設(shè)定所有的路由都走這個(gè)中間件

<?php namespace App\Http\Middleware;
use Illuminate\Support\Facades\Session;
use Closure;
class Permission {
  /**
   * Handle an incoming request.
   *
   * @param \Illuminate\Http\Request $request
   * @param \Closure $next
   * @return mixed
   */
  public function handle($request, Closure $next)
  {
    $permits = $this->getPermission($request);
    $admin = \App\Http\Middleware\Authenticate::getAuthUser();
    // 只要有一個(gè)有權(quán)限,就可以進(jìn)入這個(gè)請(qǐng)求
    foreach ($permits as $permit) {
      if ($permit == &#39;*&#39;) {
        return $next($request);
      }
      if ($admin->hasPermission($permit)) {
        return $next($request);
      }
    }
    echo "沒有權(quán)限,請(qǐng)聯(lián)系管理員";exit;
  }
  // 獲取當(dāng)前路由需要的權(quán)限
  public function getPermission($request)
  {
    $actions = $request->route()->getAction();
    if (empty($actions[&#39;permissions&#39;])) {
      echo "路由沒有設(shè)置權(quán)限";exit;
    }
    return $actions[&#39;permissions&#39;];
  }
}

這裡最關(guān)鍵的就getPermission函數(shù),從$request->route()->getAction ()來取得這個(gè)路由的action定義,然後從其中的permissions欄位中取得route.php定義的路由權(quán)限。

然後上面的middleware有個(gè):

admin?>hasPermission(admin?>hasPermission(permit);

這個(gè)就牽涉到??model的設(shè)計(jì)。

model設(shè)計(jì)

<?php namespace App\Models\Admin;
use App\Models\Model as BaseModel;
class Admin extends BaseModel {
  protected $table = &#39;admin&#39;;
  // 判斷是否有某個(gè)權(quán)限
  public function hasPermission($permission)
  {
    $permission_db = $this->permissions;
    if(in_array($permission, $permission_db)) {
      return true;
    }
    return false;
  }
  // permission 是一個(gè)二維數(shù)組
  public function getPermissionsAttribute($value)
  {
    if (empty($value)) {
      return [];
    }
    $data = json_decode($value, true);
    $ret = [];
    foreach ($data as $key => $value) {
      $ret[] = $key;
      foreach ($value as $value2) {
        $ret[] = "{$key}.{$value2}";
      }
    }
    return array_unique($ret);
  }
  // 全局設(shè)置permission
  public function setPermissionsAttribute($value)
  {
    $ret = [];
    foreach ($value as $item) {
      $keys = explode(&#39;.&#39;, $item);
      if (count($keys) != 2) {
        continue;
      }
      $ret[$keys[0]][] = $keys[1];
    }
    $this->attributes[&#39;permissions&#39;] = json_encode($ret);
  }
}

在資料庫(kù)中,我將二維數(shù)組儲(chǔ)存為json,利用laravel的Attribute的get和set方法,完成了資料庫(kù)中json和外界程式邏輯的連接。然後hasPermission就顯得很輕鬆了,直接判斷in_array就ok了。

後續(xù)

這個(gè)權(quán)限認(rèn)證的邏輯就清晰了。然後如果頁面中某個(gè)tab或nav需要對(duì)不同權(quán)限的使用者展示,只需要在view中判斷

@if ($admin->hasPermission(&#39;admin.index&#39;))
@endif

就可以判斷這個(gè)使用者是否可以看到這個(gè)tab了。

總結(jié)

這個(gè)是一個(gè)不算複雜的用戶權(quán)限實(shí)現(xiàn),但是我感覺已經(jīng)能滿足大部分的後臺(tái)需求了。當(dāng)然可以最佳化的點(diǎn)可能很多,
例如permission是不是可以支援正規(guī),hasPermission如果儲(chǔ)存在nosql或pg中,是不是不用進(jìn)行json的資料解析,直接一個(gè)DB請(qǐng)求就能判斷是否有permission之類的?

希望本文所述對(duì)大家基於Laravel框架的PHP程式設(shè)計(jì)有所幫助。

更多Laravel5權(quán)限管理方法詳解相關(guān)文章請(qǐng)關(guān)注PHP中文網(wǎng)!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願(yuàn)投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請(qǐng)聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)程式碼編輯軟體(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72