国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > PHP > 正文

laravel實(shí)現(xiàn)簡單用戶權(quán)限的示例代碼

2024-05-05 00:09:17
字體:
供稿:網(wǎng)友

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

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

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

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

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

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

基本決定好了就開干。

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

基本的路由是這樣的

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

這里在基本的制定路由action之后設(shè)置了一個permissions的屬性,這個屬性設(shè)計(jì)成數(shù)組,因?yàn)楸热缫粋€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è)計(jì)

好了,下面我們就掛上中間件,并且設(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)限,就可以進(jìn)入這個請求    foreach ($permits as $permit) {      if ($permit == '*') {        return $next($request);      }      if ($admin->hasPermission($permit)) {        return $next($request);      }    }    echo "沒有權(quán)限,請聯(lián)系管理員";exit;  }  // 獲取當(dāng)前路由需要的權(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(permit); 這個就涉及到model的設(shè)計(jì)。

model設(shè)計(jì)

<?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)限認(rèn)證的邏輯就清晰了。然后如果頁面中某個tab或者nav需要對不同權(quán)限的用戶展示,只需要在view中判斷

@if ($admin->hasPermission('admin.index')) @endif

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

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持VeVb武林網(wǎng)。


注:相關(guān)教程知識閱讀請移步到PHP教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 宁津县| 长沙县| 古浪县| 舒城县| 简阳市| 通许县| 巫山县| 日土县| 格尔木市| 兴城市| 桂东县| 改则县| 仙桃市| 平和县| 朔州市| 河北省| 蓝田县| 扎鲁特旗| 浦县| 屏边| 武乡县| 商水县| 小金县| 潼关县| 新和县| 武安市| 克什克腾旗| 许昌县| 京山县| 开平市| 罗山县| 泗洪县| 繁峙县| 高唐县| 中西区| 秭归县| 镇宁| 武宁县| 沂水县| 珠海市| 永寿县|