Files
wordpress-theme-aksrt/inc/classes/auth/class-aksrt-auth-router.php
T
kate522 ce1c13b947 refactor(classes): organize inc/classes into domain folders
Move ~94 root class shells and root *-traits into domain directories
(core, auth, user, credits, content, payment/gateways, forum, shop,
sms, ai, messages, extensions, widgets, settings, admin). Update
bootstrap require paths, co-locate traits with owners, fix forum/user
relative requires, drop duplicate shop controller requires, and wire
home-modules load. Path-only; class names and init order unchanged.
2026-07-17 11:11:57 +08:00

218 lines
6.4 KiB
PHP

<?php
/**
* AKSRT Theme Auth Router
*
* 统一处理主题内认证路由:
* - /login
* - /register
* - /bind-account
* - /reset-password
* - /logout
* - wp-login.php 前台分流
*
* @package AKSRT
*/
defined('ABSPATH') || exit;
final class AKSRT_Auth_Router {
private static $instance = null;
public static function get_instance(): self {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {}
public function init(): void {
add_filter('query_vars', [$this, 'register_query_vars']);
add_action('init', [$this, 'register_rewrite_rules']);
add_filter('template_include', [$this, 'handle_template_include'], 99);
add_action('init', [$this, 'maybe_flush_rewrite_rules']);
add_filter('login_url', [$this, 'filter_login_url'], 10, 3);
add_filter('lostpassword_url', [$this, 'filter_lostpassword_url'], 10, 2);
add_filter('register_url', [$this, 'filter_register_url']);
add_filter('logout_url', [$this, 'filter_logout_url'], 10, 2);
add_action('login_init', [$this, 'redirect_native_login']);
add_action('template_redirect', [$this, 'handle_logout_route']);
}
public function register_query_vars(array $vars): array {
$vars[] = 'aksrt_sign';
$vars[] = 'aksrt_auth_tab';
$vars[] = 'aksrt_logout';
return $vars;
}
private function auth_route_map(): array {
return [
'login' => 'index.php?aksrt_sign=1&aksrt_auth_tab=login',
'register' => 'index.php?aksrt_sign=1&aksrt_auth_tab=register',
'bind-account' => 'index.php?aksrt_sign=1&aksrt_auth_tab=bind',
'logout' => 'index.php?aksrt_logout=1',
'reset-password' => 'index.php?aksrt_sign=1&aksrt_auth_tab=reset-password',
'verify-email' => 'index.php?aksrt_sign=1&aksrt_auth_tab=verify-email',
];
}
public function register_rewrite_rules(): void {
foreach ($this->auth_route_map() as $path => $query) {
add_rewrite_rule('^' . preg_quote($path, '/') . '/?$', $query, 'top');
}
}
public function handle_template_include(string $template): string {
if (get_query_var('aksrt_sign')) {
// §4.1 Global sign gate: when close_sign is active, block non-logged-in access to sign page
if (class_exists('AKSRT_Settings') && AKSRT_Settings::close_sign() && !is_user_logged_in()) {
$tab = (string) get_query_var('aksrt_auth_tab');
if (!in_array($tab, ['reset-password', 'verify-email', 'bind-account'], true) && empty($_REQUEST['interim-login'])) {
if (!headers_sent()) {
wp_safe_redirect(home_url('/'), 302);
exit;
}
}
}
$auth_template = function_exists('aksrt_get_auth_template_file')
? aksrt_get_auth_template_file((string) get_query_var('aksrt_auth_tab'), true)
: 'templates/pages/page-sign.php';
$tpl = aksrt_locate_template_file($auth_template);
if ($tpl) {
return $tpl;
}
}
return $template;
}
public function maybe_flush_rewrite_rules(): void {
$rewrite_version = AKSRT_VERSION . ':sign-router-v1';
if (get_option('aksrt_auth_routes_flushed') !== $rewrite_version) {
flush_rewrite_rules(false);
update_option('aksrt_auth_routes_flushed', $rewrite_version);
}
}
public function filter_login_url(string $login_url, string $redirect, bool $force_reauth): string {
if (strpos($login_url, 'wp-login.php') === false) {
return $login_url;
}
$custom_login_url = aksrt_get_login_url();
if ($redirect !== '') {
$custom_login_url = add_query_arg('redirect_to', urlencode($redirect), $custom_login_url);
}
if ($force_reauth) {
$custom_login_url = add_query_arg('reauth', '1', $custom_login_url);
}
return $custom_login_url;
}
public function filter_lostpassword_url(string $lostpassword_url, string $redirect): string {
$custom_url = aksrt_get_reset_password_url();
if ($redirect !== '') {
$custom_url = add_query_arg('redirect_to', urlencode($redirect), $custom_url);
}
return $custom_url;
}
public function filter_register_url(string $register_url): string {
return aksrt_get_register_url();
}
public function filter_logout_url(string $logout_url, string $redirect): string {
return aksrt_get_logout_url($redirect ?: home_url('/'));
}
public function redirect_native_login(): void {
if (wp_doing_ajax()) {
return;
}
// §4.1 Emergency bypass key (admin_sign_key): allow wp-login.php direct access when key matches
if (isset($_GET['aksrt_bypass'])) {
$key = class_exists('AKSRT_Settings') ? AKSRT_Settings::admin_sign_key() : '';
if ($key !== '' && hash_equals($key, (string) $_GET['aksrt_bypass'])) {
return;
}
}
$action = isset($_REQUEST['action']) ? sanitize_key((string) $_REQUEST['action']) : 'login';
$redirect_to = isset($_REQUEST['redirect_to']) ? wp_unslash((string) $_REQUEST['redirect_to']) : '';
$interim = !empty($_REQUEST['interim-login']);
$reauth = !empty($_REQUEST['reauth']);
$is_admin_target = $redirect_to !== '' && strpos($redirect_to, admin_url()) === 0;
if (is_user_logged_in() && current_user_can('manage_options')) {
return;
}
if ($is_admin_target || $interim || $reauth || $action === 'logout') {
return;
}
switch ($action) {
case 'register':
$target = aksrt_get_register_url();
break;
case 'lostpassword':
$target = aksrt_get_reset_password_url();
break;
case 'rp':
case 'resetpass':
$target = add_query_arg('legacy', '1', aksrt_get_reset_password_url());
break;
default:
$target = aksrt_get_login_url();
break;
}
$passthrough = [];
if ($redirect_to !== '') {
$passthrough['redirect_to'] = $redirect_to;
}
if ($reauth) {
$passthrough['reauth'] = '1';
}
if (!empty($_REQUEST['obk'])) {
$passthrough['obk'] = sanitize_text_field((string) $_REQUEST['obk']);
}
if (!empty($passthrough)) {
$target = add_query_arg($passthrough, $target);
}
wp_safe_redirect($target, 302);
exit;
}
public function handle_logout_route(): void {
if (!get_query_var('aksrt_logout')) {
return;
}
if (!is_user_logged_in()) {
wp_safe_redirect(home_url('/'));
exit;
}
$nonce = isset($_GET['_wpnonce']) ? sanitize_text_field((string) $_GET['_wpnonce']) : '';
if (!wp_verify_nonce($nonce, 'aksrt-logout')) {
wp_die(__('退出登录请求无效,请重试。', 'aksrt'));
}
$redirect_to = isset($_GET['redirect_to']) ? wp_unslash((string) $_GET['redirect_to']) : home_url('/');
wp_logout();
wp_safe_redirect($redirect_to ?: home_url('/'));
exit;
}
}