搜尋
首頁php教程PHP视频Laravel5權限管理方法詳解

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

關於權限管理的思考

最近用laravel設計後台,後台需要有個權限管理。權限管理實質上分為兩個部分,首先是認證,然後是權限。認證部分非常好做,就是管理員登錄,記錄session。這個laravel中也有自備Auth來實現這個。最麻煩就是權限認證。

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

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

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

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

基本上決定好了就開乾。

路由設計

基本的路由是這樣的

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

這裡在基本的製定路由action之後設定了一個permissions的屬性,這個屬性設計成數組,因為例如一個post請求,它可能在某個頁面會觸發,也可能在另一個頁面觸發,那麼這個post請求就需要同時擁有兩個頁面路由的權限。

這裡使用admin.validate的權限控制,這樣,可以將權限分組,admin都是關於admin相關的分組,在資料庫中,我就會儲存一個二維數組,[admin] => ['validate', 'index']; 儲存成二維數組而不是一維的好處呢,一般後台展示是有兩個維度的,一個是頭部的tab欄,一個是左邊的nav欄,就是說這個二維的數組和後台的tab,nav欄是一一對應的。

中間件設計

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

<?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();
    // 只要有一个有权限,就可以进入这个请求
    foreach ($permits as $permit) {
      if ($permit == &#39;*&#39;) {
        return $next($request);
      }
      if ($admin->hasPermission($permit)) {
        return $next($request);
      }
    }
    echo "没有权限,请联系管理员";exit;
  }
  // 获取当前路由需要的权限
  public function getPermission($request)
  {
    $actions = $request->route()->getAction();
    if (empty($actions[&#39;permissions&#39;])) {
      echo "路由没有设置权限";exit;
    }
    return $actions[&#39;permissions&#39;];
  }
}

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

然後上面的middleware有個:

admin−>hasPermission(admin−>hasPermission(permit);

這個就牽涉到​​model的設計。

model設計

<?php namespace App\Models\Admin;
use App\Models\Model as BaseModel;
class Admin extends BaseModel {
  protected $table = &#39;admin&#39;;
  // 判断是否有某个权限
  public function hasPermission($permission)
  {
    $permission_db = $this->permissions;
    if(in_array($permission, $permission_db)) {
      return true;
    }
    return false;
  }
  // permission 是一个二维数组
  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);
  }
  // 全局设置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);
  }
}

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

後續

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

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

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

總結

這個是一個不算複雜的用戶權限實現,但是我感覺已經能滿足大部分的後台需求了。當然可以最佳化的點可能很多,
例如permission是不是可以支援正規,hasPermission如果儲存在nosql或pg中,是不是不用進行json的資料解析,直接一個DB請求就能判斷是否有permission之類的?

希望本文所述對大家基於Laravel框架的PHP程式設計有所幫助。

更多Laravel5權限管理方法詳解相關文章請關注PHP中文網!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱工具

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境