WordPress多站点子域名重置密码重定向及邮件发送失败问题排查
解决WordPress多站点子域名重置密码重定向+邮件发送失败问题
咱们一步一步拆解这个问题:你遇到的其实是两个关联问题——那款重定向插件为了修复跳转逻辑,强行替换了邮件发送方式,和你原本的SendGrid配置冲突;而重定向问题本身其实不用插件也能搞定,还不会破坏邮件功能。
第一步:换掉出问题的插件,用代码修复重定向
那款插件大概率是硬编码用了PHP原生的mail()函数,但你的站点一直靠SendGrid的SMTP发邮件,服务器大概率禁用了mail()(毕竟用SendGrid也不需要它),所以一启用插件就炸了。咱们不用它,直接加代码解决重定向:
把下面的代码加到你当前子主题的functions.php文件里,或者创建一个简单的自定义插件(避免主题更新丢失代码):
// 修复丢失密码页面的URL,指向当前子站点 add_filter('lostpassword_url', 'custom_subsite_lostpassword_url', 10, 2); function custom_subsite_lostpassword_url($url, $redirect) { if (is_multisite() && !is_main_site()) { $current_blog = get_blog_details(); // 生成当前子站点的重置密码链接 $url = network_site_url("wp-login.php?action=lostpassword", 'login'); $url = str_replace(get_network()->domain, $current_blog->domain, $url); } return $url; } // 修复重置密码成功后的重定向,跳回子站点 add_action('login_redirect', 'custom_subsite_reset_redirect', 10, 3); function custom_subsite_reset_redirect($redirect_to, $request, $user) { if (isset($_GET['action']) && $_GET['action'] === 'resetpass' && is_multisite() && $user instanceof WP_User) { $user_blogs = get_blogs_of_user($user->ID); // 匹配用户当前访问的子站点 foreach ($user_blogs as $blog) { if ($blog->domain === $_SERVER['HTTP_HOST']) { $redirect_to = get_site_url($blog->blog_id, '/wp-login.php?action=rp&key=' . $_GET['key'] . '&login=' . $_GET['login']); break; } } } return $redirect_to; }
这段代码的作用:
- 生成丢失密码的链接时,自动替换成当前子站点的域名,而非主站
- 重置密码完成后,自动跳回用户操作的子站点,不会跑到主站去
第二步:确保SendGrid邮件配置不被干扰
既然之前没插件时邮件正常,说明你的SendGrid配置是对的,但要防止其他代码覆盖它。如果是用SendGrid官方插件,确保插件是最新版本,并且在网络后台(多站点主管理后台)配置好API密钥;如果是用代码配置SMTP,把下面的代码也加上(同样放functions.php或自定义插件):
// 强制WordPress用SendGrid SMTP发送邮件 add_action('phpmailer_init', 'setup_sendgrid_smtp'); function setup_sendgrid_smtp($phpmailer) { $phpmailer->isSMTP(); $phpmailer->Host = 'smtp.sendgrid.net'; $phpmailer->SMTPAuth = true; $phpmailer->Port = 587; $phpmailer->Username = 'apikey'; // 固定填这个,不用改 $phpmailer->Password = '你的SendGrid API密钥'; // 替换成你的实际密钥 $phpmailer->SMTPSecure = 'tls'; $phpmailer->From = 'noreply@example.com'; // 替换成你的发件邮箱 $phpmailer->FromName = '你的站点名称'; // 替换成你的站点名 }
这段代码会直接强制PHPMailer使用SendGrid的SMTP,不管其他插件怎么折腾,都不会用到服务器的mail()函数,也就不会出现那个错误提示了。
第三步:测试验证
- 先禁用那款导致邮件错误的插件
- 把上面的代码都加好
- 用子站点的用户账号请求重置密码,检查收到的邮件里的链接是不是子站点域名
- 点击链接重置密码,完成后看看是不是跳回子站点的登录页,同时确认邮件正常发送
另外提一句:你的PHP7.0和WordPress4.9版本都比较老,安全风险较高,能升级的话尽量升级到支持的新版本,但上面的代码在当前版本里应该能正常运行。
内容的提问来源于stack exchange,提问作者EqSan
相关产品推荐
相关产品推荐

