WooCommerce:安全重定向未登录用户的自定义账户页面端点
发布时间:2025-12-05 13:37
发布者:网络
浏览次数:
本文详细介绍了如何解决woocommerce中未登录用户意外访问“我的账户”页面及其自定义端点的问题。通过利用`template_redirect`钩子和精确的条件逻辑,教程展示了如何确保只有已登录用户才能访问这些受保护的页面,同时允许“找回密码”等特定页面对未登录用户开放,从而提升网站的安全性和用户体验。
在WooCommerce开发中,有时我们希望“我的账户”页面及其所有子页面(包括自定义端点)仅对已登录用户可见。例如,当网站设计要求登录/注册表单以弹窗形式展示,而非通过默认的“我的账户”页面时,就需要实现这种重定向机制。这不仅关乎用户体验,更是网站安全性的重要组成部分,防止未授权访问敏感信息或功能。
理解问题:未登录用户访问“我的账户”端点
最初的重定向尝试通常会针对“我的账户”主页面进行,但往往忽略了其下方的自定义端点。当用户在未登录状态下直接访问如 my-account/my_returns 这样的自定义端点时,原有的重定向逻辑可能无法生效,导致用户看到不应出现的登录表单或页面内容。
初始重定向逻辑示例(存在局限性):
add_action( 'template_redirect', 'wish_custom_redirect' );
function wish_custom_redirect() {
global $wp;
if (
!is_user_logged_in()
&&
('my-account' == $wp->request) // 仅针对 'my-account' 主页面
&&
('lost-password' != $wp->request) // 排除 'lost-password'
)
{
wp_redirect( home_url() );
exit;
}
}这段代码的问题在于,('my-account' == $wp->request) 这一条件只精确匹配了“我的账户”主页的请求路径。当请求路径是 my-account/my_returns 时,$wp->request 的值会是 my-account/my_returns,与 'my-account' 不匹配,因此重定向不会触发。
WooCommerce自定义端点的创建
为了更好地理解重定向的必要性,我们首先回顾一下WooCommerce中自定义端点的典型创建流程。这个过程涉及添加重写规则、注册查询变量、将端点添加到账户菜单以及为端点添加内容。
地方门户新闻文章资讯模板(带手机端)1.4.2
地方门户新闻文章资讯模板(带手机端)自带内核安装即用,可根据需求增加表单、搜索等功能,前端图片文本均支持可视化,支持伪静态,多种内容模型,会员登录等。功能特点:1、安装即用,自带人人站CMS内核及企业站展示功能(产品,新闻,案例展示等),并可根据需要增加表单 搜索等功能(自带模板)2、自带手机端3、前端banner轮播图文本均已进行可视化配置4、伪静态页面生成5、支持内容模型、多语言、自定义表单、
0
查看详情
-
注册新的重写端点: 使用 add_rewrite_endpoint() 函数为“我的账户”页面添加一个新的URL端点。
function ts_custom_add_my_returns_endpoint() { add_rewrite_endpoint( 'my_returns', EP_ROOT | EP_PAGES ); } add_action( 'init', 'ts_custom_add_my_returns_endpoint' ); -
添加新的查询变量: 注册与端点对应的查询变量,以便WordPress识别。
function ts_custom_my_returns_query_vars( $vars ) { $vars[] = 'my_returns'; return $vars; } add_filter( 'woocommerce_get_query_vars', 'ts_custom_my_returns_query_vars', 0 ); -
插入到“我的账户”菜单: 将新端点添加到“我的账户”导航菜单中。
function ts_custom_add_my_returns_link_my_account( $items ) { $items['my_returns'] = 'My returns'; return $items; } add_filter( 'woocommerce_account_menu_items', 'ts_custom_add_my_returns_link_my_account' ); -
为端点添加内容: 使用 woocommerce_account_{endpoint_slug}_endpoint 钩子为自定义端点填充内容。
function ts_custom_my_returns_content() { // 在此处添加端点页面的具体
内容,例如显示退货订单列表
?>
<h2 class="text-center woocommerce-products-header__title page-title need-title"><?php echo get_theme_mod('my_returns_tab_heading') ?></h2>
<section class="order">
<?php
$orders = wc_get_orders( array(
'numberposts' => -1,
'orderby' => 'date',
'order' => 'DESC',
'customer_id' => get_current_user_id(),
'status' => array('refunded','cancelled'),
) );
foreach( $orders as $order ){
// ... 订单内容展示逻辑 ...
}
?>
</section>
<?php
}
add_action( 'woocommerce_account_my_returns_endpoint', 'ts_custom_my_returns_content' );注意: 在添加或修改重写规则后,务必访问WordPress后台的“设置” > “固定链接”页面,并点击“保存更改”按钮,以刷新重写规则,否则可能会出现404错误。
解决方案:扩展重定向逻辑以包含自定义端点
要正确地重定向未登录用户对“我的账户”主页面及其所有自定义端点的访问,我们需要更精细的条件判断。关键在于使用逻辑或 (||) 运算符来组合多个页面路径的匹配,同时通过逻辑与 (&&) 运算符确保用户未登录且排除特定页面。
以下是经过优化的重定向代码:
add_action('template_redirect', 'wish_custom_redirect_extended');
function wish_custom_redirect_extended()
{
global $wp; // 访问全局 $wp 对象,其中包含当前请求的路径
// 定义需要保护的账户页面端点列表
// 这里的 'my-account' 是主页,'my_returns' 是一个自定义端点
// 您可以根据需要添加更多自定义端点,例如 'my_addresses', 'edit-account' 等
$protected_endpoints = array(
'my-account',
'my-account/my_returns', // 示例自定义端点
// 添加其他需要保护的自定义端点,例如:
// 'my-account/my_wishlist',
// 'my-account/orders',
// 'my-account/edit-account',
// 'my-account/edit-address',
// 'my-account/payment-methods',
// 'my-account/customer-logout', // 通常应允许登出,但如果需要重定向也可以包含
);
// 检查当前请求路径是否在受保护的端点列表中
$is_protected_endpoint = false;
foreach ($protected_endpoints as $endpoint) {
// 匹配精确路径或以该路径开头的任何子路径
// 例如,如果 $wp->request 是 'my-account/orders/view-order/123'
// 那么 'my-account/orders' 应该匹配
if (strpos($wp->request, $endpoint) === 0) {
$is_protected_endpoint = true;
break;
}
}
// 综合判断是否需要重定向
if (
!is_user_logged_in() // 用户未登录
&&
$is_protected_endpoint // 且当前页面是受保护的账户页面或其子页面
&&
('lost-password' != $wp->request) // 排除“找回密码”页面
) {
// 使用 wp_safe_redirect() 进行安全重定向到网站首页
wp_safe_redirect(site_url());
exit; // 终止脚本执行
}
}
// 确保用户登出后也重定向到首页,防止返回缓存页面
add_action('wp_logout','auto_redirect_after_logout');
function auto_redirect_after_logout(){
wp_safe_redirect( home_url() );
exit();
}代码解释与最佳实践
- $wp->request: 这个全局变量包含了当前请求的干净URL路径(不含域名和查询参数)。它是判断用户访问哪个页面的关键。
- !is_user_logged_in(): 这是一个WordPress核心函数,用于检查当前用户是否已登录。
-
$protected_endpoints 数组和循环:
- 我们定义了一个数组 $protected_endpoints 来列出所有需要保护的“我的账户”相关路径。这使得代码更易于维护和扩展。
- 通过循环遍历这个数组,并使用 strpos($wp->request, $endpoint) === 0 来检查当前请求路径是否以任何一个受保护的端点开头。这种方式可以捕获主端点及其所有子端点(例如,my-account 会匹配 my-account、my-account/orders 等)。
- ('lost-password' != $wp->request): 这一条件至关重要,它确保“找回密码”页面对未登录用户是可访问的,这是恢复账户的必要功能。
-
wp_safe_redirect(site_url()):
- wp_safe_redirect() 是WordPress推荐的重定向函数,它比 wp_redirect() 更安全,因为它会验证重定向URL,防止开放重定向漏洞。
- site_url() 返回WordPress网站的URL,即重定向的目标地址。
- exit;: 在重定向后,务必调用 exit; 来终止脚本的进一步执行,防止在重定向发生后仍然输出其他内容。
- wp_logout 钩子: 额外添加的 wp_logout 钩子确保用户在登出后立即被重定向到网站首页,防止他们使用浏览器后退按钮返回到可能包含敏感信息的缓存页面。
实施步骤
-
选择放置位置: 将上述优化后的代码片段添加到您的主题的 functions.php 文件中。
- 推荐做法: 最好将其放置在一个子主题的 functions.php 文件中,这样在更新父主题时不会丢失您的自定义代码。
- 更专业的做法: 创建一个自定义插件来管理这类功能,这有助于代码的模块化和可移植性。
-
测试:
- 清除网站缓存(如果使用了缓存插件)。
- 使用不同的浏览器或隐身模式,在未登录状态下尝试直接访问“我的账户”主页 (/my-account/) 和您创建的自定义端点 (/my-account/my_returns/)。
- 确认这些页面都成功重定向到了网站首页。
- 测试“找回密码”页面 (/my-account/lost-password/),确保它仍然可以正常访问。
- 登录后测试,确保已登录用户可以正常访问所有“我的账户”页面和端点。
通过以上步骤和代码,您可以有效地控制WooCommerce中“我的账户”页面及其自定义端点的访问权限,确保只有已登录用户才能查看这些内容,从而提升网站的安全性和用户体验。
以上就是WooCommerce:安全重定向未登录用户的自定义账户页面端点的详细内容,更多请关注php中文网其它相关文章!
# php
# word
# go
# wordpress
# 浏览器
# 注册表
# red
# 自定义
# 重定向
# 重写
# 自带
# 表单
# 首页
# 运算符
# 找回密码
# 您的
# 上传
# 棋牌推广营销策划公司
# 湖南创意seo上线时间
# 德州品牌网站维护推广
# shopee怎么查关键词排名
# seo系统算法服务程序
# 重庆公司网站怎么建设
# 淮南关键词排名提升公司
# 南京营销推广十大排名
# 福田网站搭建设计
# 耒阳企业网站建设





内容,例如显示退货订单列表
?>
<h2 class="text-center woocommerce-products-header__title page-title need-title"><?php echo get_theme_mod('my_returns_tab_heading') ?></h2>
<section class="order">
<?php
$orders = wc_get_orders( array(
'numberposts' => -1,
'orderby' => 'date',
'order' => 'DESC',
'customer_id' => get_current_user_id(),
'status' => array('refunded','cancelled'),
) );
foreach( $orders as $order ){
// ... 订单内容展示逻辑 ...
}
?>
</section>
<?php
}
add_action( 'woocommerce_account_my_returns_endpoint', 'ts_custom_my_returns_content' );