登陸

用戶

上一篇:PHP如何禁止外網訪問 下一篇:Laravel 5.5 發布,ThinkSNS+ 升級及狀況分享

色坐标系:不使用三方包時,如何在ThinkSNS中建立優雅的用戶權限管理

榮華軟件  1656  1   2017-12-21 16:06

三d连线带坐标走势图 www.gjvgfb.com.cn

需求場景

就是用戶組+權限節點,這個需求 laravel 有很多很好的第三方包實現。下面描述代碼不參與緩存機制純數據庫查詢,給大家提供一個思路。

下面的代碼都是來自于ThinkSNS+,是基于 Laravel 全新開發的 ThinkSNS 社交開源項目,遵循 Apache2.0 開源協議?;隊?Star 哦。

數據表設計

其實這一塊我個人是參考的 Zizaco/entrust 因為我覺得,大多數情況下,我們要用的角色和權限節點都是真多用戶的。數據表設計如下:

h7SGVm84q9.png

可以看到關系如下 user > role > ability ,其中關系全部都是多對多關系。一個用戶可以擁有多個 role,一個 ability 可以被分配給多個 role 。

鏈式方法設計

$user>ability('create user'); // 判斷是否有 create user 權限。
$user>ability('owner', 'delete user'); // 判斷用戶是否擁有 owner 用戶組,且是否這個組擁有 delete user 權限。
$user>ability(); // 返回一個 Ability 實例。
$user>roles;  // 讀取用戶所擁有的所有用戶組。
$user>roles(); // 獲取 Builder 實例。
$user>roles('owner'); // 檢查用戶是否擁有 owner 用戶組,擁有返回 model 實例,否則返回 false。
$user>ability()>roles(); // 讀取用戶所擁有的所有用戶組。返回的是一個 集合??捎眉纖蟹椒?。
$user>ability()>roles('owner'); // 檢查用戶是否擁有 owner 用戶組,擁有返回 model 實例,否則返回 false。
$user>ability()>all(); // 返回用戶擁有的所有權限集合。
$user>ability()>all('create user'); // 檢查用戶是否擁有 create user 權限,沒有返回 false ,有返回 ability 實例。

其中調用 $user>ability()>all() 和 $user>ability()>all() 都是返回的 集合 可以鏈式調用集合下的所有方法進一步操作。

ability 用戶 Trait

    /
    public function ability(...$parameters)
    {
        if (isset($parameters[1])) {
            return ($role = $this>resolveAbility()>roels($parameters[0]))
                ? $role>ability($parameters[1])
                : false;
        } elseif (isset($parameters[0])) {
            return $this>resolveAbility()
                >all($parameters[0]);
        }

        return $this>resolveAbility();
    }

    /
      The user all roles.
     
      @param string $role
      @return mied
      @author Seven Du 
     /
    public function roles(string $role = '')
    {
        if ($role) {
            return $this>ability()>roles($role);
        }

        return $this>belongsToMany(Role::class, 'role_user', 'user_id', 'role_id');
    }

    /
      Resolve ability service.
     
      @return hiyiPlusServicesUserAbility
      @author Seven Du 
     /
    protected function resolveAbility()
    {
        if (! ($this>ability instanceof UserAbility)) {
            $this>ability = new UserAbility();
        }

        return $this>ability>setUser($this);
    }
}

Ability 實例

    /
    public function roles(string $role = '')
    {
        $roles = $this>user()
            >roles()
            >get()
            >keyBy('name');

        if (! $role) {
            return $roles;
        }

        return $roles>get($role, false);
    }
    /
      Get all abilities or get first ability.
     
      @param string $ability
      @return mixed
      @author Seven Du 
     /
    public function all(string $ability = '')
    {
        $roles = $this>roles();
        $roles>load('abilities');
        $abilities = $roles>reduce(function ($collect, $role) {
            return $collect>merge(
                $role>abilities>keyBy('name')
            );
        }, new Collection());

        if (! $ability) {
            return $abilities;
        }

        return $abilities>get($ability, false);
    }
    /
      Get user instance.
     
      @return hiyiPlusModelsUser
      @author Seven Du 
     /
    public function user(): UserModel
    {
        return $this>user;
    }
    /
      Set user model.
     
      @param hiyiPlusModelsUser $user
      @author Seven Du 
     /
    public function setUser(UserModel $user)
    {
        $this>user = $user;
        return $this;
    }
}

Role 模型所需代碼

    /
    public function abilities()
    {
        return $this>belongsToMany(Ability::class, 'ability_role', 'role_id', 'ability_id');
    }
    /
      Get or check The role ability.
     
      @param string $ability
      @return false|UserPlusModelsAbility
      @author Seven Du 
     /
    public function ability(string $ability)
    {
        return $this>abilities>keyBy('name')>get($ability, false);
    }
}

使用

然后我們打開 User 模型wen jia文件添加如下代碼:

class User ...
{
    use UserHasAbility;
}

總結

其實性狀在 User 模型中只暴露了 roles 和 ability 兩個公開方法。但是已經足以勝任用戶組權限判斷邏輯了。

整個 ability 都是結合在集合之上的一些封裝,這樣是的代碼調用更加優雅。

以上代碼是在開發ThinkSNS+中的實際真實代碼。具體的實現可參考項目。

以上代碼都來自于ThinkSNS Plus,看完整的開發代碼可以看倉庫:

GitHub: https://github.com/slimkit/thinksnsplus(開源不易,求 Star )

1條回答

  • 榮華軟件

    很正確,測試可用

    2018-02-01

登陸后可回復

  1. 登陸
  2. 注冊
服務熱線

400-692-8081

( 周一至周五 09:00-17:00 )

聯系我們

名稱:煙臺榮華軟件科技有限公司

地址:煙臺市高新區航天路101號C棟5樓516

座機:0535-3458081

郵箱:[email protected]

Q Q:327195471

[email protected] 煙臺榮華軟件科技有限公司 版權所有 魯ICP備14003838號-1