后臺管理頁面的訪問權限
在cmf的simplewind/cmf/controller/AdminBaseController.php文件中,使用函數checkAccess($userid)判斷此登陸用戶是否有權限訪問此頁面。
/**
* 檢查后臺用戶訪問權限
* @param int $userId 后臺用戶id
* @return boolean 檢查通過返回true
*/
private function checkAccess($userId)
{
// 如果用戶id是1,則無需判斷
if ($userId == 1) {
return true;
}
$module = $this->request->module();
$controller = $this->request->controller();
$action = $this->request->action();
$rule = $module . $controller . $action;
$notRequire = ["adminIndexindex", "adminMainindex"];
if (!in_array($rule, $notRequire)) {
return cmf_auth_check($userId);
} else {
return true;
}
}
在這個函數里首先判斷用戶是不是超級管理員用戶,如果是,不用檢查權限,直接放行。如果訪問的是后臺主界面等所有人都可以訪問的公共界面,也直接放行。否則調用cmf_auth_check()函數檢查權限。
轉到cmf_auth_check()函數看看
```
/**
* 檢查權限
* @param $userId int 要檢查權限的用戶 ID
* @param $name string|array 需要驗證的規則列表,支持逗號分隔的權限規則或索引數組
* @param $relation string 如果為 'or' 表示滿足任一條規則即通過驗證;如果為 'and'則表示需滿足所有規則才能通過驗證
* @return boolean 通過驗證返回true;失敗返回false
*/
function cmf_auth_check($userId, $name = null, $relation = 'or')
{
if (empty($userId)) {
return false;
}
if ($userId == 1) {
return true;
}
$authObj = new \cmf\lib\Auth();
if (empty($name)) {
$request = request();
$module = $request->module();
$controller = $request->controller();
$action = $request->action();
$name = strtolower($module . "/" . $controller . "/" . $action);
}
return $authObj->check($userId, $name, $relation);
}
```
但是這個函數并沒有什么實質內容,只是將當前的路徑當成參數調用另一個類里的函數,所以繼續跟蹤。
\cmf\lib\Auth()->check()
/**
* 檢查權限
* @param $name string|array 需要驗證的規則列表,支持逗號分隔的權限規則或索引數組
* @param $uid int 認證用戶的id
* @param $relation string 如果為 'or' 表示滿足任一條規則即通過驗證;如果為 'and'則表示需滿足所有規則才能通過驗證
* @return boolean 通過驗證返回true;失敗返回false
*/
public function check($uid, $name, $relation = 'or')
{
if (empty($uid)) {
return false;
}
if ($uid == 1) {
return true;
}
if (is_string($name)) {
$name = strtolower($name);
if (strpos($name, ',') !== false) {
$name = explode(',', $name);
} else {
$findAuthRuleCount = Db::name('auth_rule')->where([
'name' => $name
])->count();
if ($findAuthRuleCount == 0) {//沒有規則時,不驗證!
return true;
}
$name = [$name];
}
}
$list = []; //保存驗證通過的規則名
$groups = Db::name('RoleUser')
->alias("a")
->join('__ROLE__ r', 'a.role_id = r.id')
->where(["a.user_id" => $uid, "r.status" => 1])
->column("role_id");
if (in_array(1, $groups)) {
return true;
}
if (empty($groups)) {
return false;
}
$rules = Db::name('AuthAccess')
->alias("a")
->join('__AUTH_RULE__ b ', ' a.rule_name = b.name')
->where(["a.role_id" => ["in", $groups], "b.name" => ["in", $name]])
->select();
foreach ($rules as $rule) {
if (!empty($rule['condition'])) { //根據condition進行驗證
$user = $this->getUserInfo($uid);//獲取用戶信息,一維數組
$command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $rule['condition']);
//dump($command);//debug
@(eval('$condition=(' . $command . ');'));
if ($condition) {
$list[] = strtolower($rule['name']);
}
} else {
$list[] = strtolower($rule['name']);
}
}
if ($relation == 'or' and !empty($list)) {
return true;
}
$diff = array_diff($name, $list);
if ($relation == 'and' and empty($diff)) {
return true;
}
return false;
}
這才是真正的權限檢查函數啊…首先還是例行的判斷是否超級管理員,再判斷傳入的需要驗證的路徑是否有多組(以逗號分隔),如果有多組,分隔開后作為數組存入原變量。如果只有一組,直接查詢表auth_rule其中是否有這條驗證規則,如果沒有就不用驗證了,直接返回true。
接下來聯合RoleUser和__ROLE__兩張表,當表中有當前用戶且用戶狀態正常時,返回當前用戶的role_id(可能有多個角色,所以為數組),如果當前用戶擁有超級管理員角色,放行;如果什么角色也沒有,拒絕請求。
在繼續聯合AuthAccess和__AUTH_RULE__兩張表,找出此用戶此次請求訪問的頁面中有權限訪問的頁面,存入$rules數組中。遍歷$rules數組,如果當前行的condition列不為空,………..(沒看懂);如果condition為空,則將當前行的name值存入數組list中,表示已經通過權限驗證的頁面。
如果list數組中不為空且驗證規則的連接詞為or(即只要有一個驗證條件通過驗證),則返回true,放行;如果連接詞為and,則對比傳入的規則列表與通過驗證的規則列表(即$name與$list),若兩個數組一致,則表明所有驗證列表都通過了驗證,返回true。否則,其他所有情況都返回false,拒絕請求。
- 空白目錄
- thinkcmf的權限管理
- thinkcmf+unicmf添加頁面
- Thinkphp5做后臺 Uni-app做前臺解決跨域問題
- 組件
- h5跨域-uniapp
- thinkphp5 auth 教程
- thinkphp5Auth類
- uniapp添加與編輯的差別
- 常見的請求方式
- uni 單選回顯數據_uniapp 頁面跳轉傳值和接收
- uni-app 單選/多選/滑動 demo
- 關于uniapp checkbox多選框如何傳值傳數據
- uniApp 多選框checkbox ,判斷是否選中
- uniapp添加復選框和獲取復選框的值
- uni-app中全選多選單選
- uniapp多選框CheckBox 數據接收
- uniapp下拉列表單選框復選框實戰demo(編輯或詳情頁)
- uni-data-CheckBox-OK
- js 字符串數組轉換成數字數組
- js把字符串轉為數組對象
- js中數組對象字符串的相互轉換
- JS怎么把字符串數組轉換成整型數組
- 小程序開發
- tp5.1跨域請求
- uniapp-h5跨域
- 新增
- order
- uni-app中調取接口的三種方式與封裝uni.request()
- uView-checkbox
- 給u-view的u-select賦值
- uView-下拉框、復選框、單選框 數據發送及接收
- CURD操作
- thinkphp5.1增刪改查
- TP5.1添加數據成功之后返回自增主鍵id
- Thinkphp實戰之Request默認值except only 以及過濾參
- uni-app跨域解決方案
- thinkphp5.1+uni-app接口開發中跨域問題解決方案
- tp6 + uniapp 前后端跨域解決方案
- uniapp-token相關
- uniapp request請求封裝包含token兼容多端,簡單易用
- CORS.php
- ThinkPHP6 API開發前后端分離用戶信息保存在后端的方法
- thinkphp的jwt(JSON Web Token)身份驗證
- thinkphp6增刪改查
- PHP模擬GET,POST請求
- php模擬get、post發送請求的6種方法
- thinkphp6
- uniapp封裝網絡請求
- thinkphp6搭建后端api接口jwt-auth
- uniapp實現APP微信登錄流程
- [uni-app] 中保持用戶登錄狀態
- 詳解vue中localStorage的使用方法
- vue 實現通過vuex 存儲值 在不同界面使用
- dispatch:異步操作,數據提交至 actions ,可用于向后臺提交數據
- ThinkPHP6.0 + Vue + ElementUI + axios 的環境安裝到實現 CURD 操作
- tp6錯誤集
- TP6 模型插入/添加數據,自動插入時間(自動時間戳)
- 手機不開機維修思路
- thinkphp6解決vue跨域問題
- 從0基礎獲取短視頻去水印解析接口制作
- thinkphp5 刪除緩存
- thinkPHP,怎么把json文件里面的數據導入數據庫
- 數字轉字符php
- php – 直接用curl下載遠程文件
- thinkphp – 直接用curl下載遠程文件
- apiAdmin安裝
- echart
- thinkphp開發小程序推廣分享帶參數二維碼生成
- php同比增加函數
- PHP獲取同比上周、上一個月,上一個季度,去年時間區間
- “前3秒”金句100例,趕緊收藏起來!
- PHP配合微信公眾號生成推廣二維碼
- thinkphp5+php微信公眾號二維碼掃碼關注推廣二維碼事件實現
- 獲取當前時間上一周的開始時間和結束時間
- TP6 查找指定工作日
- PHP 獲取當天、近一周、本周、上月、本月、本季度、上季度時間方法大全
- php獲取今日、昨日、本周、本月 日期方法
- Tp5+mysql按年季度月周日小時查詢時無數據的時間段補0方法
- mysql按天統計的時候,該天沒有數據也要統計為0
- 列出一星期的日期 無數據補0
- thinkphp6本周 上周 周一 周末日期
- 補全日期 無數據補0
- php+pv統計代碼實現,Laravel 10 行代碼實現簡單的網站 pv uv 統計
- 通過API獲取ip地址以及城市和運營商
- 獲取訪客信息
- 13行代碼實現微信小程序設置概率觸發激勵視頻閱讀文章
- uniapp 微信小程序 獲取場景值和場景值個性化參數
- 微信小程序分享小程序碼的生成(帶參數)以及參數的獲取
- 小程序推廣分享帶參數二維碼生成
- uniapp微信小程序生成對應頁面二維碼
- uniapp獲取當前頁面url
- uniapp微信小程序--微信登錄
- 微信小程序,生成小程序碼中scene參數的存放和獲取問題
- uni-app 微信小程序生成二維碼帶參數
- uni-app 微信小程序如何把圖片保存到本地相冊?
- thinkPHP5使用assign()傳遞富文本,前端解析成HTML標簽
- tp6解析編輯器里面的html標簽原樣輸出
- PHP判斷url鏈接是否被百度收錄
- 微擎安裝模塊時提示 Failed to connect to we7.rewlkj.com port 80: Timed out
- 小程序碼生成
- thinkphp開發小程序推廣分享帶參數二維碼生成0
- tp3.2偽靜態
- apiadmin安裝教程-2022.8更新
- autojs事件代碼
- uuuu
- thinkphp6: API 多版本控制