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

Please explain conception how to sign outgoing emails in Laravel 9 with a DKIM signature. Laravel 9 uses Symfony mailer. I'm trying to proceed by this way:

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;
    }
}

Error

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)



Solution 1:[1]

There is other way to sign outgoing emails in Laravel 9 with a DKIM signature (without any tool):

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());
            });
    }
}

Solution 2:[2]

There is a tool that will solve your problem. You can get it here and this is how you use it:

Install package with composer using: composer require simonschaufi/laravel-dkim

In the config/app.php file, comment Illuminate\Mail\MailServiceProvider::class line and add the following line with dkim package service provider: SimonSchaufi\LaravelDKIM\DKIMMailServiceProvider::class

Publish the config file using the artisan command: php artisan vendor:publish --provider="SimonSchaufi\LaravelDKIM\DKIMMailServiceProvider"

Configure your dkim settings in your .env file:

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

This tool solves the problem using a custom Mailer with dkim signature:

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Rafael Angel Di Gregorio Ruíz
Solution 2