
本文详细介绍了如何解决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中自定义端点的典型创建流程。这个过程涉及添加重写规则、注册查询变量、将端点添加到账户菜单以及为端点添加内容。
注册新的重写端点: 使用 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() { // 在此处添加端点页面的具体内容,例如显示退货订单列表 ?> -1, 'orderby' => 'date', 'order' => 'DESC', 'customer_id' => get_current_user_id(), 'status' => array('refunded','cancelled'), ) ); foreach( $orders as $order ){ // ... 订单内容展示逻辑 ... } ?> <?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中文网其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1341359.html
微信扫一扫
支付宝扫一扫