如何使用 DKIM 签名对 Laravel 9 中的外发电子邮件进行签名

How to sign outgoing emails in Laravel 9 with a DKIM signature

请解释如何使用 DKIM 签名在 Laravel 9 中签署外发电子邮件的概念。 Laravel 9 使用 Symfony 邮件程序。我正在尝试通过这种方式进行:

class ContactForm extends Mailable
{
    use Queueable, SerializesModels;

    public $mailData;

    public function __construct($mailData)
    {
        $this->mailData = $mailData;
    }

    public function build()
    {
        $this->subject($this->mailData['subject'])
            ->view('mail.contact-form')
            ->text('mail.contact-form_plain');

        $this->withSymfonyMessage(function (Email $message) {
            $signer = new DkimSigner(config('mail.dkim_private_key'), config('mail.dkim_domain'),
            config('mail.dkim_selector'));
            $signer->sign($message);
        });

        return $this;
    }
}

错误

local.ERROR: A message must have a text or an HTML part or attachments. {"exception":"[object] (Symfony\Component\Mime\Exception\LogicException(code: 0): A message must have a text or an HTML part or attachments. at E:\WebProjects\domains\hostbrook\vendor\symfony\mime\Email.php:390)

有一个工具可以解决您的问题。您可以获得它 here 并且您可以这样使用它:

使用 composer 安装包:composer require simonschaufi/laravel-dkim

config/app.php 文件中,注释 Illuminate\Mail\MailServiceProvider::class 行并添加以下带有 dkim 包服务提供商的行:SimonSchaufi\LaravelDKIM\DKIMMailServiceProvider::class

使用 artisan 命令发布配置文件:php artisan vendor:publish --provider="SimonSchaufi\LaravelDKIM\DKIMMailServiceProvider"

.env 文件中配置 dkim 设置:

DKIM_PRIVATE_KEY=your_txt_private_key_path // Required. Indicates your private key txt file configured previously. By default, the storage path app/dkim/private_key.txt is used
DKIM_SELECTOR=your_dkim_record_selector // Required. If this value is empty, <code>default</code> is used
DKIM_DOMAIN=your_dkim_domain // Required. Indicates the domain of your dkim record configured previously
DKIM_PASSPHRASE=your_dkim_passphrase // Optional
DKIM_ALGORITHM=your_dkim_algorithm // Required. By default, rsa-sha256 is used
DKIM_IDENTITY=your_dkim_identity // Optional

此工具使用带有 dkim 签名的自定义 Mailer 解决了问题:

$signer = new DkimSigner(file_get_contents($privateKey), $domain, $selector, [], config('dkim.passphrase'));
$signedEmail = $signer->sign($message->getSymfonyMessage());
$symfonyMessage->setHeaders($signedEmail->getHeaders());

还有其他方法可以使用 DKIM 签名(无需任何工具)对 Laravel 9 中的外发电子邮件进行签名:

class ContactForm extends Mailable
{
    use Queueable, SerializesModels;

    public $mailData;

    public function __construct($mailData)
    {
        $this->mailData = $mailData;
    }

    public function build()
    {
        $mailData = $this->mailData;

        $htmlView = 'mail.contact-form';
        $plainView = 'mail.contact-form_plain';

        $htmlEmail = view($htmlView, compact('mailData'))->render();
        $plainEmail = view($plainView, compact('mailData'))->render();

        return $this->subject($this->mailData['subject'])
            ->view($htmlView)
            ->text($plainView)
            ->withSymfonyMessage(function (Email $message) use ($htmlEmail, $plainEmail) {
                $message
                    ->html($htmlEmail)
                    ->text($plainEmail);

                $signer = new DkimSigner(
                    config('mail.dkim_private_key'),
                    config('mail.dkim_domain'),
                    config('mail.dkim_selector')
                );

                $signedEmail = $signer->sign($message);

                $message->setHeaders($signedEmail->getHeaders());
            });
    }
}