Laravel5權(quán)限管理方法詳解
本文實例講述了Laravel5權(quán)限管理的實現(xiàn)方法。分享給大家供大家參考,具體如下:
關(guān)于權(quán)限管理的思考
最近用laravel設(shè)計后臺,后臺需要有個權(quán)限管理。權(quán)限管理實質(zhì)上分為兩個部分,首先是認證,然后是權(quán)限。認證部分非常好做,就是管理員登錄,記錄session。這個laravel中也有自帶Auth來實現(xiàn)這個。最麻煩就是權(quán)限認證。
權(quán)限認證本質(zhì)上就是誰有權(quán)限管理什么東西。這里有兩個方面的維度,誰,就是用戶維度,在用戶維度,權(quán)限管理的粒度可以是用戶一個人,也可以是將用戶分組,如果將用戶分組,則涉及到的邏輯是一個用戶可以在多個組里面嗎?在另外一方面,管理什么東西,這個東西是物的維度,一個頁面是一個東西,一個頁面上的一個元素也是一個東西,或者往大了說,一個功能是一個東西。所以做權(quán)限管理最重要的是確認這兩個維度的粒度。這個已經(jīng)不是技術(shù)的事情了,這個是需要需求討論的了。
基于上面的思考,我這次想做的權(quán)限管理,在用戶維度,是基于個人的。就是每個人的權(quán)限不一樣。在東西的維度,我設(shè)置路由為最小的單位,即可以為單個路由設(shè)置權(quán)限管理。
下面的思考就是使用什么來標記權(quán)限,可以使用位,也可以使用字符,也可以使用整型。后來我選擇了字符,基于兩點考慮:1 字符淺顯易懂,在數(shù)據(jù)庫中查找也比較方便 2 我沒有按照某個權(quán)限查找有這個權(quán)限的人的需求,即沒有反查需求,使用位,整型等都意義不大。
接下來考慮如何和laravel結(jié)合,既然要為每個路由設(shè)置訪問權(quán)限,那么我當然希望能在laravel的route.php路由管理中配置。最好就是在Route::get的時候有個參數(shù)能設(shè)置permission。這樣做的好處是權(quán)限設(shè)置簡易了。在決定路由的時候,就順手寫了權(quán)限控制。壞處呢,也很明顯,laravel路由的三種方式只能寫一種了。就是Route::(method)這樣的方式了。
基本決定好了就開干。
路由設(shè)計
基本的路由是這樣的
這里在基本的制定路由action之后設(shè)置了一個permissions的屬性,這個屬性設(shè)計成數(shù)組,因為比如一個post請求,它可能在某個頁面會觸發(fā),也可能在另外一個頁面觸發(fā),那么這個post請求就需要同時擁有兩個頁面路由的權(quán)限。
這里使用admin.validate的權(quán)限控制,這樣,可以將權(quán)限分組,admin都是關(guān)于admin相關(guān)的分組,在數(shù)據(jù)庫中,我就會存儲一個二維數(shù)組,[admin] => ['validate', 'index']; 存儲成二維數(shù)組而不是一維的好處呢,一般后臺展示是有兩個維度的,一個是頭部的tab欄,一個是左邊的nav欄,就是說這個二維的數(shù)組和后臺的tab,nav欄是一一對應(yīng)的。
中間件設(shè)計
好了,下面我們就掛上中間件,并且設(shè)置所有的路由都走這個中間件
<?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(); // 只要有一個有權(quán)限,就可以進入這個請求 foreach ($permits as $permit) { if ($permit == '*') { return $next($request); } if ($admin->hasPermission($permit)) { return $next($request); } } echo "沒有權(quán)限,請聯(lián)系管理員";exit; } // 獲取當前路由需要的權(quán)限 public function getPermission($request) { $actions = $request->route()->getAction(); if (empty($actions['permissions'])) { echo "路由沒有設(shè)置權(quán)限";exit; } return $actions['permissions']; } }
這里最關(guān)鍵的就getPermission函數(shù),從$request->route()->getAction()來獲取出這個路由的action定義,然后從其中的permissions字段中獲取route.php中定義的路由權(quán)限。
然后上面的middleware有個:
admin−>hasPermission(admin−>hasPermission(permit);
這個就涉及到model的設(shè)計。
model設(shè)計
<?php namespace App\Models\Admin; use App\Models\Model as BaseModel; class Admin extends BaseModel { protected $table = 'admin'; // 判斷是否有某個權(quán)限 public function hasPermission($permission) { $permission_db = $this->permissions; if(in_array($permission, $permission_db)) { return true; } return false; } // permission 是一個二維數(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('.', $item); if (count($keys) != 2) { continue; } $ret[$keys[0]][] = $keys[1]; } $this->attributes['permissions'] = json_encode($ret); } }
在數(shù)據(jù)庫中,我將二維數(shù)組存儲為json,利用laravel的Attribute的get和set方法,完成了數(shù)據(jù)庫中json和外界程序邏輯的連接。然后hasPermission就顯得很輕松了,直接判斷in_array就ok了。
后續(xù)
這個權(quán)限認證的邏輯就清晰了。然后如果頁面中某個tab或者nav需要對不同權(quán)限的用戶展示,只需要在view中判斷
@if ($admin->hasPermission('admin.index')) @endif
就可以判斷這個用戶是否可以看到這個tab了。
總結(jié)
這個是一個不算復雜的用戶權(quán)限實現(xiàn),但是我感覺已經(jīng)能滿足大部分的后臺需求了。當然可以優(yōu)化的點可能很多,
比如permission是不是可以支持正則,hasPermission如果存儲在nosql或者pg中,是不是不用進行json的數(shù)據(jù)解析,直接一個DB請求就能判斷是否有permission之類的?
更多關(guān)于Laravel相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Laravel框架入門與進階教程》、《php優(yōu)秀開發(fā)框架總結(jié)》、《smarty模板入門基礎(chǔ)教程》、《php日期與時間用法總結(jié)》、《php面向?qū)ο蟪绦蛟O(shè)計入門教程》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫操作入門教程》及《php常見數(shù)據(jù)庫操作技巧匯總》
希望本文所述對大家基于Laravel框架的PHP程序設(shè)計有所幫助。
- 在Laravel5中正確設(shè)置文件權(quán)限的方法
- Laravel框架實現(xiàn)的rbac權(quán)限管理操作示例
- laravel實現(xiàn)簡單用戶權(quán)限的示例代碼
- 解決laravel中日志權(quán)限莫名變成了root的問題
- laravel利用中間件做防非法登錄和權(quán)限控制示例
- Laravel5.1數(shù)據(jù)庫連接、創(chuàng)建數(shù)據(jù)庫、創(chuàng)建model及創(chuàng)建控制器的方法
- laravel5.1框架基礎(chǔ)之Blade模板繼承簡單使用方法分析
- Laravel5.1框架注冊中間件的三種場景詳解
- laravel5.1框架基礎(chǔ)之路由詳解
- laravel5.1框架model類查詢的實現(xiàn)方法
- Laravel5.1框架自帶權(quán)限控制系統(tǒng) ACL用法分析
相關(guān)文章
Yii視圖CGridView實現(xiàn)操作按鈕定義地址示例
這篇文章主要介紹了Yii視圖CGridView實現(xiàn)操作按鈕定義地址的方法,涉及Yii視圖按鈕操作相關(guān)技巧,需要的朋友可以參考下2016-07-07Thinkphp5.0 框架的請求方式與響應(yīng)方式分析
這篇文章主要介紹了Thinkphp5.0 框架的請求方式與響應(yīng)方式,結(jié)合實例形式分析了thinkPHP5常見的請求方式與響應(yīng)方式實現(xiàn)技巧與操作注意事項,需要的朋友可以參考下2019-10-10php序列化函數(shù)serialize() 和 unserialize() 與原生函數(shù)對比
這篇文章主要介紹了php序列化函數(shù)serialize() 和 unserialize() 與php原生序列化方法對比,有需要的小伙伴可以參考下。2015-05-05Laravel框架基于中間件實現(xiàn)禁止未登錄用戶訪問頁面功能示例
這篇文章主要介紹了Laravel框架基于中間件實現(xiàn)禁止未登錄用戶訪問頁面功能,結(jié)合實例形式分析了Laravel框架中間件生成、注冊及使用相關(guān)操作技巧,需要的朋友可以參考下2019-01-01PHP+Memcache實現(xiàn)wordpress訪問總數(shù)統(tǒng)計(非插件)
這篇文章主要介紹了PHP+Memcache實現(xiàn)wordpress訪問總數(shù)統(tǒng)計,直接寫在主題functions.php中,并非實現(xiàn)的一個插件,需要的朋友可以參考下2014-07-07