WordPress 6.9 版本发件人地址:小疏忽如何导致邮件被拒(WPJAM-SMTP)

AI摘要

WordPress邮件系统的发件人地址(Envelope-From)若与SMTP邮箱地址不匹配,在现代SPF和DMARC安全协议下会导致邮件被拒。WordPress 6.9默认使用wordpress@home_url(),可通过插件(如WPJAM Basic)的`wp_mail_from`过滤器将其统一为SMTP邮箱地址,确保一致性,避免投递失败。

在邮件系统中,发件人地址(也称为Envelope-From、MAIL FROM或Return-Path)是一个关键但常被忽视的概念。这是其他邮件服务器在无法投递邮件时发送"退信"的地址。

WordPress中的发件人地址演变

自WordPress 4.7.0以来,该值由外发邮件服务器设置,默认使用wordpress@home_url()。表面上看,配置错误似乎只是导致站点收不到投递失败通知的小问题,但在现代邮件安全协议下,这已演变成更严重的隐患。

SPF和DMARC:问题的根源

发件人策略框架(SPF)DMARC系统旨在阻止垃圾邮件传播,但它们会完全拒绝那些发件人地址不匹配的合法邮件。这就使得原本的小问题变成了可能导致邮件被拒的大问题。

以WordPress 6.9为例,使用WPJAM Basic的SMTP功能测试时,就会出现发件人地址与SMTP邮箱地址不一致的错误。

WordPress 6.9 解决方案

WordPress 6.9以可扩展的方式设置了发件人地址:

  • 如果邮件头中存在From地址,则使用该地址
  • 否则,默认使用wordpress@home_url()
  • 插件可以通过wp_mail_from Filter来过滤发件人地址

解决方案很简单:在WPJAM Basic的SMTP扩展中加入一行代码(/wp-content/plugins/wpjam-basic/extends/wpjam-smtp.php的60行):

add_filter('wp_mail_from', fn()=> self::get_setting('user'));

这样WordPress就会把发件人地址设置为SMTP邮箱地址,确保一致性。

完整的代码:

<?php
/*
Name: SMTP 发信
URI: https://mp.weixin.qq.com/s/SbuvSL01hT3Jxp9doWZ8zg
Description: SMTP 发信可以让你使用第三方邮箱的 SMTP 服务来发送邮件。
Version: 2.0
*/
class WPJAM_SMTP extends WPJAM_Option_Model{
	public static function get_fields(){
		return [
			'smtp_setting'		=> ['title'=>'SMTP 设置',	'type'=>'fieldset',	'fields'=>[
				'host'	=> ['title'=>'SMTP地址',	'type'=>'text',		'class'=>'',	'value'=>'smtp.qq.com'],
				'user'	=> ['title'=>'邮箱账号',	'type'=>'email',	'class'=>''],
				'pass'	=> ['title'=>'邮箱密码',	'type'=>'password',	'class'=>''],
				'ssl'	=> ['title'=>'发送协议',	'type'=>'text',		'class'=>'',	'value'=>'ssl'],
				'port'	=> ['title'=>'SSL端口',	'type'=>'number',	'class'=>'',	'value'=>'465'],
			]],
			'mail_from_name'	=> ['title'=>'发送者姓名',	'type'=>'text',	'class'=>''],
			'reply_to_mail'		=> ['title'=>'回复地址',		'type'=>'email','class'=>'',	'description'=>'不填则用户回复使用SMTP设置中的邮箱账号']
		];
	}

	public static function get_form(){
		return [
			'submit_text'	=> '发送',
			'callback'		=> fn($data)=> wp_mail($data['to'], $data['subject'], $data['message']),
			'validate'		=> true,
			'fields'		=> [
				'to'		=> ['title'=>'收件人',	'type'=>'email',	'required'],
				'subject'	=> ['title'=>'主题',		'type'=>'text',		'required'],
				'message'	=> ['title'=>'内容',		'type'=>'textarea',	'class'=>'',	'required'],
			]
		];
	}

	public static function on_phpmailer_init($phpmailer){
		if(!array_all(['host', 'user', 'pass'], fn($k)=> self::get_setting($k))){
			return;
		}

		$phpmailer->Mailer		= 'smtp';
		$phpmailer->SMTPAuth	= true;
		$phpmailer->SMTPSecure	= self::get_setting('ssl', 'ssl');
		$phpmailer->Host		= self::get_setting('host'); 
		$phpmailer->Port		= self::get_setting('port', '465');
		$phpmailer->Username	= self::get_setting('user');
		$phpmailer->Password	= self::get_setting('pass');

		$from_name	= self::get_setting('mail_from_name', '');
		$reply_to	= self::get_setting('reply_to_mail'); 

		$phpmailer->setFrom(self::get_setting('user'), $from_name, false);

		$reply_to && $phpmailer->AddReplyTo($reply_to, $from_name);
		
	}

	public static function add_hooks(){
		add_action('phpmailer_init',	[self::class, 'on_phpmailer_init']);
        add_filter('wp_mail_from', fn()=> self::get_setting('user'));

		(wp_doing_ajax() || wpjam_is_json_request()) && add_action('wp_mail_failed', 'wpjam_send_json');
	}
}

wpjam_register_option('wpjam-smtp',	[
	'model'		=> 'WPJAM_SMTP',
	'title'		=> '发信设置',
	'menu_page'	=> [
		'parent'		=> 'wpjam-basic',
		'page_title'	=> 'SMTP 发信',
		'network'		=> false,
		'summary'		=> __FILE__,
		'function'		=> 'tab',
		'tabs'			=> [
			'smtp'	=> ['title'=>'发信设置',	'function'=>'option'],
			'send'	=> ['title'=>'发送测试',	'function'=>'form',	'form'=>['WPJAM_SMTP', 'get_form']]
		]
	]
]);

WordPress 6.9的其他邮件优化

除了发件人地址问题,WordPress 6.9还修复了两个重要但不易察觉的邮件问题:

修复邮件编码持久化问题

wp_mail()调用全局的$phpmailer对象发送邮件,这意味着同一PHP请求中的多次调用会共享状态。PHPMailer会根据消息因素设置编码头,由于对象是全局的,这些编码更改会持续存在并应用到后续邮件中。

6.9的改进:在发送每封邮件前,内部编码都会被重置,确保PHPMailer能根据服务器配置和特定消息细节为每封邮件分配合适的编码类型。

为多部分邮件分配正确的内容类型

过去十七年间,WordPress与PHPMailer在处理多部分消息时存在一个潜伏的Bug:WordPress向PHPMailer发送了损坏的ContentType,导致PHPMailer进一步损坏外发消息。

6.9的解决方案:通过依赖PHPMailer自身的功能来设置内容类型,而不是手动指定该头,简化了修复过程。

Saiyintai

软件测试工程师

相关推荐

Wordpress 文章网站卡片插件:Custom Card

Custom Card Plugin 是一个用于在 WordPress 网站中快速添加美观的卡片布局的插件。支持灵活的内容展示,包括图片、标题、描述文字和链接,适用于博客文章中插入网站的场景。

暂无评论