
開放會員註冊的 WordPress 網站(會員專區、線上課程、購物網站),會員登入之後,預設會被帶到後台的「個人資料」頁,畫面上方還有一條黑色工具列。對會員來說,這個長得像管理系統的畫面很陌生,也會破壞網站整體的感覺。
這篇整理怎麼讓沒有編輯權限的帳號(訂閱者、購物網站的顧客)一進後台就被導回首頁,後台只留給管理員與寫文章的人使用。
(原本另一篇〈用代碼讓 WordPress 的預設角色無法進入後台〉的內容,已經整合到這裡。)
先了解:這是「整理畫面」,不是資安防護
訂閱者就算進得了後台,也只看得到控制台和自己的個人資料,改不了文章、外掛或設定。所以這篇的程式碼主要是讓會員的使用體驗一致,不是用來擋駭客。後台登入的安全防護請看WordPress 登入安全怎麼做?。
WordPress 內建的角色,大致能做這些事:
- 網站管理員:什麼都能做。
- 編輯:可以管理所有人的文章與頁面。
- 作者:可以發表、管理自己的文章。
- 投稿者:可以寫自己的文章,但要審核後才會發表。
- 訂閱者:只能管理自己的個人資料。
更完整的角色與權限說明,可以看WordPress 角色和權限終極指南。
程式碼要放在哪裡?
下面的程式碼加在子主題的 functions.php 最後面,或用 Code Snippets 外掛新增一段程式碼。不要直接改佈景主題本身的檔案,主題一更新就會被覆蓋。
動手前先備份,並確認自己會用 FTP 或主機的檔案管理員把程式碼拿掉,萬一寫錯才救得回來。
做法一:沒有編輯權限的帳號一律導回首頁(推薦)
/**
* 沒有「編輯文章」權限的帳號(訂閱者、顧客等)
* 進入後台時一律導回首頁
*/
add_action( 'admin_init', function () {
// AJAX 請求要放行,前台的表單、購物車等功能都會用到
if ( wp_doing_ajax() ) {
return;
}
// admin-post.php 是前台表單送出資料的入口,也要放行
global $pagenow;
if ( 'admin-post.php' === $pagenow ) {
return;
}
// 網站管理員、編輯、作者、投稿者照常使用後台
if ( current_user_can( 'edit_posts' ) ) {
return;
}
wp_safe_redirect( home_url( '/' ) );
exit;
} );幾個重點:
- 用
edit_posts判斷:這個權限只有投稿者以上的角色才有,訂閱者和 WooCommerce 的顧客都沒有。用它判斷,寫文章的人不會被誤擋。 - 一定要排除
wp_doing_ajax():前台很多功能是透過wp-admin/admin-ajax.php送資料,這個檔案也會觸發admin_init。沒有排除的話,會員送出表單、加入購物車都可能失敗。 admin-post.php也要放行:部分外掛的前台表單會把資料送到這裡,同樣會觸發admin_init,而且沒登入的訪客也會用到。- 用
wp_safe_redirect()加上exit:只允許導向自己網站的網址,導向後立刻停止執行,後台頁面不會繼續輸出。
想導到其他頁面(例如會員中心),把 home_url( '/' ) 改成 home_url( '/member/' ) 這種自己網站的網址即可。
做法二:只擋「新使用者預設角色」
如果你只想擋註冊進來的新會員,也就是「設定 → 一般」裡設定的新使用者預設角色(通常是訂閱者),可以改用這個版本:
add_action( 'admin_init', function () {
if ( wp_doing_ajax() ) {
return;
}
global $pagenow;
if ( 'admin-post.php' === $pagenow ) {
return;
}
// 保險起見:網站管理員永遠不擋
if ( current_user_can( 'manage_options' ) ) {
return;
}
$user = wp_get_current_user();
if ( in_array( get_option( 'default_role' ), (array) $user->roles, true ) ) {
wp_safe_redirect( home_url( '/' ) );
exit;
}
} );get_option( 'default_role' ) 會取得網站設定的預設角色,$user->roles 是這個帳號擁有的所有角色,用 in_array() 比對,帳號有多個角色時也不會判斷錯。
做法一和做法二選一種就好,不要兩段都加。
只讓網站管理員進後台?
舊版文章用的是 current_user_can( 'manage_options' ),也就是只有網站管理員能進後台。這樣一來,編輯、作者也會被擋在外面,沒辦法寫文章。除非網站只有管理員會發文,否則建議用做法一的 edit_posts。
搭配:隱藏前台的工具列
被導回首頁的會員,在前台還是會看到上方的工具列,上面還有「控制台」的連結。加上這段,讓沒有編輯權限的人看不到工具列:
add_filter( 'show_admin_bar', function ( $show ) {
return current_user_can( 'edit_posts' ) ? $show : false;
} );工具列的其他設定方式,可以看WordPress 隱藏上方工具列。
搭配:登入後直接回到前台
會員從 wp-login.php 登入後,WordPress 預設會把他帶到後台,再被上面的程式碼導回首頁,等於多跳一次。用 login_redirect 讓他登入後直接回前台:
add_filter( 'login_redirect', function ( $redirect_to, $requested_redirect_to, $user ) {
if ( $user instanceof WP_User
&& ! $user->has_cap( 'edit_posts' )
&& str_starts_with( $redirect_to, admin_url() ) ) {
return home_url( '/' );
}
return $redirect_to;
}, 10, 3 );只有「登入後要去後台」的情況才會改成首頁。如果會員是從某個前台頁面點「登入」過來、登入後要回到原本那一頁,這段不會干擾。
舊寫法的問題
這篇 2015 年的版本,以及原本另一篇文章的寫法,現在有幾個問題:
- 用
$_SERVER['PHP_SELF']比對/wp-admin/admin-ajax.php:WordPress 裝在子資料夾(例如/blog/)時會比對不到,前台的 AJAX 功能就被擋掉了。現在直接用wp_doing_ajax()判斷。 - 用
$current_user->roles[0]取角色:這個陣列不一定有索引 0,例如帳號在這個網站沒有角色時,PHP 8 會出現「Undefined array key」的警告;帳號有多個角色時也可能判斷錯誤。 - 直接寫在
functions.php最外層:沒有掛在任何 hook 上,載入檔案時就執行,時機太早,應該放在admin_init裡。 - 沒有排除
admin-post.php:會讓部分外掛的前台表單失效。
常見問題
會員要改密碼、個人資料怎麼辦?
會員被擋在後台之外,就用不到後台的「個人資料」頁。會員外掛(或 WooCommerce 的「我的帳號」頁)通常都有前台的個人資料與修改密碼功能;忘記密碼則可以用登入頁的「忘記密碼」重新設定。
用 WooCommerce 還需要這段嗎?
WooCommerce 本身就會把沒有後台權限的顧客導到「我的帳號」頁,也會替他們隱藏工具列。如果網站的會員只有 WooCommerce 顧客,通常不需要另外加;網站還有其他會員角色時,再用這篇的程式碼補上。
加了之後,自己也被導回首頁?
先確認登入的帳號角色是不是正確。真的進不去後台時,用 FTP 或主機的檔案管理員,把剛才加在 functions.php 的程式碼刪掉;用 Code Snippets 的話,把 wp-content/plugins/ 裡的 code-snippets 資料夾暫時改名,外掛就會停用,網站恢復原狀。
延伸閱讀
- WordPress 使用者角色與權限完整指南:預設角色、檢查權限、建立自訂角色
- WordPress 會員註冊後自動登入、跳轉到指定頁面(PHP 8 安全寫法)
- WordPress 隱藏上方工具列:前台關閉、只讓管理員看到,或移到畫面下方
會員網站要好用,前台與後台誰能看到什麼,最好在規劃時就想清楚。正威網路行銷是 25 年經驗的基隆網頁設計工作室,提供客製化網頁設計與網站維護託管,歡迎來聊聊。







發表留言
還沒有人留言,歡迎第一個分享你的想法或問題。留言經審核後才會顯示,Email 不會公開。