《PHP實(shí)戰(zhàn):Laravel5權(quán)限管理方法詳解》要點(diǎn):
本文介紹了PHP實(shí)戰(zhàn):Laravel5權(quán)限管理方法詳解,希望對(duì)您有用。如果有疑問(wèn),可以聯(lián)系我們。
PHP編程本文實(shí)例講述了Laravel5權(quán)限管理的實(shí)現(xiàn)方法.分享給大家供大家參考,具體如下:
PHP編程關(guān)于權(quán)限管理的思考
PHP編程最近用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來(lái)實(shí)現(xiàn)這個(gè).最麻煩就是權(quán)限認(rèn)證.
PHP編程權(quán)限認(rèn)證本質(zhì)上就是誰(shuí)有權(quán)限管理什么東西.這里有兩個(gè)方面的維度,誰(shuí),就是用戶維度,在用戶維度,權(quán)限管理的粒度可以是用戶一個(gè)人,也可以是將用戶分組,如果將用戶分組,則涉及到的邏輯是一個(gè)用戶可以在多個(gè)組里面嗎?在另外一方面,管理什么東西,這個(gè)東西是物的維度,一個(gè)頁(yè)面是一個(gè)東西,一個(gè)頁(yè)面上的一個(gè)元素也是一個(gè)東西,或者往大了說(shuō),一個(gè)功能是一個(gè)東西.所以做權(quán)限管理最重要的是確認(rèn)這兩個(gè)維度的粒度.這個(gè)已經(jīng)不是技術(shù)的事情了,這個(gè)是需要需求討論的了.
PHP編程基于上面的思考,我這次想做的權(quán)限管理,在用戶維度,是基于個(gè)人的.就是每個(gè)人的權(quán)限不一樣.在東西的維度,我設(shè)置路由為最小的單位,即可以為單個(gè)路由設(shè)置權(quán)限管理.
PHP編程下面的思考就是使用什么來(lái)標(biāo)記權(quán)限,可以使用位,也可以使用字符,也可以使用整型.后來(lái)我選擇了字符,基于兩點(diǎn)考慮:1 字符淺顯易懂,在數(shù)據(jù)庫(kù)中查找也比較方便 2 我沒(méi)有按照某個(gè)權(quán)限查找有這個(gè)權(quán)限的人的需求,即沒(méi)有反查需求,使用位,整型等都意義不大.
PHP編程接下來(lái)考慮如何和laravel結(jié)合,既然要為每個(gè)路由設(shè)置訪問(wèn)權(quán)限,那么我當(dāng)然希望能在laravel的route.php路由管理中配置.最好就是在Route::get的時(shí)候有個(gè)參數(shù)能設(shè)置permission.這樣做的好處是權(quán)限設(shè)置簡(jiǎn)易了.在決定路由的時(shí)候,就順手寫(xiě)了權(quán)限控制.壞處呢,也很明顯,laravel路由的三種方式只能寫(xiě)一種了.就是Route::(method)這樣的方式了.
PHP編程基本決定好了就開(kāi)干.
PHP編程路由設(shè)計(jì)
PHP編程基本的路由是這樣的
PHP編程這里在基本的制定路由action之后設(shè)置了一個(gè)permissions的屬性,這個(gè)屬性設(shè)計(jì)成數(shù)組,因?yàn)楸热缫粋€(gè)post請(qǐng)求,它可能在某個(gè)頁(yè)面會(huì)觸發(fā),也可能在另外一個(gè)頁(yè)面觸發(fā),那么這個(gè)post請(qǐng)求就需要同時(shí)擁有兩個(gè)頁(yè)面路由的權(quán)限.
PHP編程這里使用admin.validate的權(quán)限控制,這樣,可以將權(quán)限分組,admin都是關(guān)于admin相關(guān)的分組,在數(shù)據(jù)庫(kù)中,我就會(huì)存儲(chǔ)一個(gè)二維數(shù)組,[admin] => ['validate', 'index']; 存儲(chǔ)成二維數(shù)組而不是一維的好處呢,一般后臺(tái)展示是有兩個(gè)維度的,一個(gè)是頭部的tab欄,一個(gè)是左邊的nav欄,就是說(shuō)這個(gè)二維的數(shù)組和后臺(tái)的tab,nav欄是一一對(duì)應(yīng)的.
PHP編程中間件設(shè)計(jì)
PHP編程好了,下面我們就掛上中間件,并且設(shè)置所有的路由都走這個(gè)中間件
PHP編程
<?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 == '*') {
return $next($request);
}
if ($admin->hasPermission($permit)) {
return $next($request);
}
}
echo "沒(méi)有權(quán)限,請(qǐng)聯(lián)系管理員";exit;
}
// 獲取當(dāng)前路由需要的權(quán)限
public function getPermission($request)
{
$actions = $request->route()->getAction();
if (empty($actions['permissions'])) {
echo "路由沒(méi)有設(shè)置權(quán)限";exit;
}
return $actions['permissions'];
}
}
PHP編程這里最關(guān)鍵的就getPermission函數(shù),從$request->route()->getAction()來(lái)獲取出這個(gè)路由的action定義,然后從其中的permissions字段中獲取route.php中定義的路由權(quán)限.
PHP編程然后上面的middleware有個(gè):
PHP編程
admin?>hasPermission(admin?>hasPermission(permit);
PHP編程這個(gè)就涉及到model的設(shè)計(jì).
PHP編程model設(shè)計(jì)
PHP編程
<?php namespace App\Models\Admin;
use App\Models\Model as BaseModel;
class Admin extends BaseModel {
protected $table = 'admin';
// 判斷是否有某個(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('.', $item);
if (count($keys) != 2) {
continue;
}
$ret[$keys[0]][] = $keys[1];
}
$this->attributes['permissions'] = json_encode($ret);
}
}
PHP編程在數(shù)據(jù)庫(kù)中,我將二維數(shù)組存儲(chǔ)為json,利用laravel的Attribute的get和set方法,完成了數(shù)據(jù)庫(kù)中json和外界程序邏輯的連接.然后hasPermission就顯得很輕松了,直接判斷in_array就ok了.
PHP編程后續(xù)
PHP編程這個(gè)權(quán)限認(rèn)證的邏輯就清晰了.然后如果頁(yè)面中某個(gè)tab或者nav需要對(duì)不同權(quán)限的用戶展示,只需要在view中判斷
PHP編程
@if ($admin->hasPermission('admin.index'))
@endif
PHP編程就可以判斷這個(gè)用戶是否可以看到這個(gè)tab了.
PHP編程總結(jié)
PHP編程這個(gè)是一個(gè)不算復(fù)雜的用戶權(quán)限實(shí)現(xiàn),但是我感覺(jué)已經(jīng)能滿足大部分的后臺(tái)需求了.當(dāng)然可以優(yōu)化的點(diǎn)可能很多,
比如permission是不是可以支持正則,hasPermission如果存儲(chǔ)在nosql或者pg中,是不是不用進(jìn)行json的數(shù)據(jù)解析,直接一個(gè)DB請(qǐng)求就能判斷是否有permission之類的?
PHP編程更多關(guān)于Laravel相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Laravel框架入門(mén)與進(jìn)階教程》、《php優(yōu)秀開(kāi)發(fā)框架總結(jié)》、《smarty模板入門(mén)基礎(chǔ)教程》、《php日期與時(shí)間用法總結(jié)》、《php面向?qū)ο蟪绦蛟O(shè)計(jì)入門(mén)教程》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫(kù)操作入門(mén)教程》及《php常見(jiàn)數(shù)據(jù)庫(kù)操作技巧匯總》
PHP編程希望本文所述對(duì)大家基于Laravel框架的PHP程序設(shè)計(jì)有所幫助.
轉(zhuǎn)載請(qǐng)注明本頁(yè)網(wǎng)址:
http://www.fzlkiss.com/jiaocheng/5069.html