iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0
WordPress

從 0 到 100:WordPress 開發者的實戰手冊系列 第 19

Day 19 - 詳解 WordPress 的使用者角色與權限控管

  • 分享至 

  • xImage
  •  

鐵人賽的進度默默地來到第 19 篇,也即將踏入開發 WordPress 外掛的篇章,期待大家即將身為外掛開發者,必須對安全性的議題非常關注,對自己寫的外掛程式權限的控管要非常小心,這是基本的責任感。

今天的主要介紹的就是 WordPress 系統中的角色與權限,熟悉今天介紹的權限管控相關的函式之後,設計外掛時遇到操作新增、修改、刪除等功能的情境,別忘了檢查使用者的角色與權限,為網站的安全性把關。

WordPress 為了實現不同使用者的有不同的登入或管理權限,實作了一個稱為「使用者角色」(user roles) 的功能,讓網站管理員可以根據使用者的貢獻度和職責分配不同的訪問和管理權限。

主要使用者角色

以下是 WordPress 中幾個主要的使用者角色及其基本權限。

中文 英文 大略說明
管理員 Administrator 能夠訪問到網站的所有管理功能。可以新增、編輯或刪除所有內容和使用者。
編輯 Editor 可以發布和管理包括其他使用者的文章在內的所有內容。無法修改網站的設定和使用者權限。
作者 Author 可以發布和管理自己的文章。無法管理其他用戶的內容或進行網站的設置變更。
貢獻者 Contributor 可以撰寫自己的文章,但不能直接發布。需要提交他們的內容供編輯者或管理員審核。無法上傳檔案。
訂閱者 Subscriber 通常只有限制的後台登入,主要是用來管理他們的使用者個人資料。無法發布文章或修改網站內容。

這些主要的使用者角色是系統內建的,從 WordPress 2.0 版開始,定義在 wp-admin\includes\schema.php 中的 populate_roles 函式中,隨著 WordPress 的功能越來越多,陸續加入新的權限以供使用。

schema.php 程式碼片段
圖:schema.php 程式碼片段

例如,第 24 行至 28 行,使用 add_role 函式加入這 5 種基本的角色。

每個使用者角色基本上是一組權限的集合。這些權限 (capabilities) 確定了一個使用者角色可以(或不能)在網站上執行的操作。例如,管理員有權限安裝外掛,而作者則沒有這個權限。

schema.php 程式碼片段
圖:schema.php 程式碼片段

同樣在 schema.php 中再往下滑一些。看到第 15 行,使用 get_role 函式取出 WP_Role 實例後,再使用這個類別的 add_cap 方法,陸續加入權限。

WordPress 的這種使用者角色分配的方式,允許網站管理者很靈活地控制不同使用者對網站的登入和管理權限,有秩序性地保持網站的日常管理。而且,通過外掛或客製化的程式碼,你還可以自行定義角色及調整不同角色的權限。

資料表

使用者角色及權限資料

在 WordPress 中,使用者角色和權限的資料是存放在資料庫的 wp_options 表中,而一個名為 wp_user_roles 的欄位中,以 PHP 序列化資料的格式儲存。

資料表 wp_options
圖:資料表 wp_options

當你使用像是 add_roleadd_cap 等函數時,WordPress 會處理這些資料並將其存放在 wp_options 表中。當你在網站上添加新角色或修改現有角色的權限時,相對應的資料會被更新。

雖然可以用 get_option( 'wp_user_roles' ) 可以從資料庫中獲取所有使用者角色和它們對應的權限。再使用 update_option( 'wp_user_roles', $new_roles ) 來更新儲存在資料庫中的使用者角色資料。不過 WordPress 有提供內建的函式來處理這個欄位的值,以確保格式正確,就沒以直接存取這個欄位的理由囉。

個別使用者的角色資料

至於個別使用者的角色為何?則是定義在 usermeta 中。

資料表 wp_usermeta
圖:資料表 wp_usermeta

一個名為 wp_capabilities 的欄位定義該使用者的角色。
另一個 wp_user_level 欄位定義該使用者的等級。

相關類別及方法

我們得知 WordPress 的使用者角色和權限資料存放在 wp_options 資料表,以及個別使用者的角色存放在 wp_usermeta 資料表,對資料的歸屬有概念後,對相關函式的操作能更理解它的作用。

函式:add_role

add_role( 'ironman' )

如果想建立一個鐵人角色,當然也可以唷!

函式:get_role

$role = get_role( 'ironman' )

這會取得角色名稱為 ironman 的 WP_Role 實例,可以用這個實例所定義的方法來為該角色進行權限的新增、修改、刪除等動作。

類別:WP_Role

在前一個 get_role 函式的說明中提到的類別名稱。

方法 說明
add_cap 給角色分配一個權限。
has_cap 判定角色是否具有給定的權限。
remove_cap 從角色中移除一個權限。

以下是一個簡單的例子,示範了如何使用 add_cap() 函數給我們剛剛建立的「鐵人」角色新增一個新的權限,讓它可以發表文章。


圖:為角色加入權限

類別:WP_User

使用 WP_User 類別實例化之後的物件,擁有以下方法,可以為該使用者設定角色:

方法 說明
set_role 為使用者設定角色。
add_role 為使用者新增角色。 
remove_role 把角色從使用者移除。

範例

  1. 獲取當前使用者的角色:
$current_user = wp_get_current_user();
$roles = ( array ) $current_user->roles;

$roles 是一個包含用戶所有角色的陣列。

  1. 為特定使用者設定角色:
$user_id = 1; // 假設用使用者 ID 為1
$user = new WP_User( $user_id );
$user->set_role( 'editor' );

這會將用使用者 ID 為 1 的使用者的角色設置為編輯。

  1. 為使用者新增角色:
$user->add_role( 'ironman' );

這將給使用者新增一個名為 ironman 的角色(前提是這個角色已經被定義)。

  1. 移除使用者的角色:
$user->remove_role( 'ironman' );

這將從使用者的角色列表中移除 ironman 角色。

提醒

本篇提到的函式和類別方法關於「新增」、「刪除」這兩種動作,程式碼會操作資料庫,必須註冊在像是「保存設定」之類的後台頁面,或啟用外掛時的鉤點,而不是 init 這類每次讀取頁面都會觸發的鉤點。它只要一次性的變更,存在資料庫後就永久生效。本篇文章示範註冊在 init 是為了讓讀者們練習時能立即看到效果的簡便寫法。

總結

相信今天的文章能讓大家充份認識 WordPress 的使用者角色如何定義,以及如何使用 WP_Role 類別來操作權限,並瞭解 WP_User 類別如何為使用者新增、刪除角色。

坊間的權限管理外掛也只是利用這些 WordPress 的內建類別及函式來做處理而已,並不是什麼神奇的魔法。瞭解了細節的作法後,或許也沒有必要裝一個肥肥的權限管理外掛,自己可以客製一個符合自己需求的外掛,追求效能和方便性的平衡,也是玩 WordPress 的樂趣哦。


課後思考:

思考並說明如何確保在調整角色和權限時,不會無意中給予使用者過多的存取權限,從而危及網站安全。

前篇解答參考:

為了達成某種便利,而刻意繞過核心的機制不是良好的習慣。正確的作法,筆者的建議會是設計一個傳統的 AJAX 入口以取得 nonce,由前端儲存在 Session Storage,每次 JavaScript 對 REST API 請求的時候都帶上 nonce。當 nonce 失效時再對提供 nonce 的 AJAX 入口發出請求來更新 Session Storage 中的 nonce 值。


上一篇
Day 18 - WordPress 的 REST API 設計與應用
下一篇
Day 20 - 使用 Rewrite API 設計客制化網址路由
系列文
從 0 到 100:WordPress 開發者的實戰手冊30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言