【问题标题】:How to customize the email verification email from Laravel 5.7?如何从 Laravel 5.7 自定义邮箱验证邮件?
【发布时间】:2022-02-03 16:29:14
【问题描述】:

我刚刚升级到 Laravel 5.7,现在我正在使用内置的电子邮件验证。但是有两件事我无法弄清楚,主要问题是如何自定义发送给用户以验证他们的电子邮件的电子邮件?如果用户更改了他们的电子邮件,我也无法弄清楚如何开始发送​​该电子邮件,但我可以将其保存到另一个线程。

【问题讨论】:

    标签: laravel-5 html-email


    【解决方案1】:

    当您想在 Laravel 5.7 中添加电子邮件验证时,建议的方法是实现 Illuminate\Contracts\Auth\MustVerifyEmail 并在 App\User 模型上使用 Illuminate\Auth\MustVerifyEmail 特征。

    要进行一些自定义行为,您可以覆盖方法sendEmailVerificationNotification,该方法通过调用方法notify 来通知创建的用户,并将Notifications\MustVerifyEmail 类的新实例作为参数传递。

    您可以创建一个自定义通知,该通知将作为参数传递给您用户模型的 sendEmailVerificationNotification 方法中的$this->notify()

    public function sendEmailVerificationNotification()
    {
        $this->notify(new App\Notifications\CustomVerifyEmail);
    }
    

    ...然后在您的CustomVerifyEmail 通知中,您可以定义处理验证的方式。您可以通过发送包含自定义 verification.route 的电子邮件来通知创建的用户,该邮件将采用您想要的任何参数。

    电子邮件验证通知流程

    当新用户注册时,App\Http\Controllers\Auth\RegisterController 中会发出一个Illuminate\Auth\Events\Registered 事件,并且该Registered 事件有一个名为Illuminate\Auth\Listeners\SendEmailVerificationNotification 的侦听器,该侦听器注册在App\Providers\EventServiceProvider 中:

    protected $listen = [
        Registered::class => [
            SendEmailVerificationNotification::class,
        ]
    ];
    

    SendEmailVerificationNotification 监听器检查 $user(在 Laravel 默认身份验证 App\Http\Controllers\Auth\RegisterController 中作为参数传递给 new Registered($user = $this->create($request->all())))是否是 Illuminate\Contracts\Auth\MustVerifyEmail 的实例,这是 Laravel 建议的特征的名称当您要提供默认电子邮件验证并检查 $user 是否尚未验证时,在 App\User 模型中使用。如果所有这些都通过了,则对该用户调用 sendEmailVerificationNotification 方法:

    if ($event->user instanceof MustVerifyEmail && !$event->user->hasVerifiedEmail())   {
        $event->user->sendEmailVerificationNotification();
    }
    

    【讨论】:

      【解决方案2】:

      我认为执行此操作的简单方法是使用此处的文档发出新通知:https://laravel.com/docs/5.7/notifications#creating-notifications

      然后重写函数:

      public function sendEmailVerificationNotification()
      {
          $this->notify(new App\Notifications\CustomEmailNotification);
      }
      

      在用户模型中。

      或者你可以

      php artisan vendor:publish --tag=laravel-notifications
      

      这会将模板复制到 resources/views/vendor/notifications 目录,您可以在那里修改它们

      【讨论】:

      • 就我而言(自定义 laravel 5.8 的默认验证电子邮件),我不得不将此答案与 Mere Development 的答案结合起来,并做一些额外的工作来完成工作。
      • 另外,查看Illuminate\Auth\Notifications\VerifyEmail 并将其与 CustomEmailNotification 进行比较。查看laravel.com/docs/5.8/mail#customizing-the-componentslaravel.com/docs/5.8/notifications 也很有用。最后一件事,我不知道为什么 CSS 主题对我不起作用,我所做的只是将我需要的所有样式直接复制到 vendor/mail/html/layout.blade.php 文件中。
      【解决方案3】:

      不幸的是,发出的这封电子邮件不是来自“视图”,而是实际上内联构建的Notification。这是当前需要发送时构建的位置:Illuminate\Auth\Notifications\VerifyEmail@toMail。这个特定的类有一个静态回调,可以设置它来构建这个电子邮件,而不是让它去做。

      boot 方法中的服务提供者中,您需要为此类分配回调:

      “类似”的东西可能会起作用:

      public function boot()
      {
          \Illuminate\Auth\Notifications\VerifyEmail::toMailUsing(function ($notifiable) {
      
              // this is what is currently being done
              // adjust for your needs
      
              return (new \Illuminate\Notifications\Messages\MailMessage)
                  ->subject(\Lang::getFromJson('Verify Email Address'))
                  ->line(\Lang::getFromJson('Please click the button below to verify your email address.'))
                  ->action(
                      \Lang::getFromJson('Verify Email Address'),
                      $this->verificationUrl($notifiable)
                  )
                  ->line(\Lang::getFromJson('If you did not create an account, no further action is required.'));
      
          });
      }
      

      由于这是一个通知,您应该有更多自定义选项。

      如果您想使用自己的 Notification 类,您可以覆盖 User (Authenticatable) 模型上的 sendEmailVerificationNotification 方法(这是来自 MustVerifyEmail 特征)。

      第二个问题:

      您应该拥有的 VerificationController (App\Http\Controllers\Auth\VerificationController) 有一个名为 resend(来自 trait VerifiesEmails)的方法,该方法看起来很适合此目的。

      您应该通过Auth::routes(['verify' => true]);为这些验证路由设置路由

      注意:

      验证系统使用 5.7 中 usersemail_verified_at 上的一个字段来标记这一点。你会想确保你有这个字段。当用户更改电子邮件地址时,我想您可以创建此 null 然后将他们重定向到 resend 路由,以发送新的验证。这将使他们进入“未验证”状态,直到他们重新验证,如果这是你打算发生的。

      更新:

      看来我们走在了正确的轨道上。我发现这个 SO 答案涵盖了类似的事情:

      Changing the default “subject” field for the verification email in laravel 5.7

      【讨论】:

      • 感谢您的帮助。你肯定让我走上了正确的道路。我还没有实现问题/答案 1,但是对于问题 2,现在只需在 User 模型上调用一个方法就可以了。 $user->sendEmailVerificationNotification();我正在处理问题 1,并将发布结果。
      • 我认为这是最好的答案,因为您向我指出了更快速的解决方案
      【解决方案4】:

      快速简便的方法:

      php artisan vendor:publish --tag=laravel-notifications
      

      它正在创建一个新文件:

      \resources\views\vendor\notifications
      

      这是 Laravel 的电子邮件模板。您可以更改和自定义它。

      【讨论】:

        【解决方案5】:

        我将向您展示如何在不使用任何供应商发布

        的情况下从头开始使用自定义视图自定义用户验证电子邮件

        步骤:1

        创建一个新通知UserVerifyNotification class。它应该从库 Illuminate\Auth\Notifications\VerifyEmail; 扩展 VerifyEmail class

        代码:

            use Illuminate\Auth\Notifications\VerifyEmail;
            ...
            class UserVerifyNotification extends VerifyEmail implements ShouldQueue
            {
                use Queueable;
                public $user;            //you'll need this to address the user
            
                /**
                 * Create a new notification instance.
                 *
                 * @return void
                 */
                public function __construct($user='')
                {
                    $this->user =  $user ?: Auth::user();         //if user is not supplied, get from session
                }
            
                /**
                 * Get the notification's delivery channels.
                 *
                 * @param  mixed  $notifiable
                 * @return array
                 */
                public function via($notifiable)
                {
                    return ['mail'];
                }
            
                /**
                 * Get the mail representation of the notification.
                 *
                 * @param  mixed  $notifiable
                 * @return \Illuminate\Notifications\Messages\MailMessage
                 */
                public function toMail($notifiable)
                {
                    $actionUrl  = $this->verificationUrl($notifiable);     //verificationUrl required for the verification link
                    $actionText  = 'Click here to verify your email';
                    return (new MailMessage)->subject('Verify your account')->view(
                        'emails.user-verify',
                        [
                            'user'=> $this->user,
                            'actionText' => $actionText,
                            'actionUrl' => $actionUrl,
                        ]);
                }
            
                /**
                 * Get the array representation of the notification.
                 *
                 * @param  mixed  $notifiable
                 * @return array
                 */
                public function toArray($notifiable)
                {
                    return [
                        //
                    ];
                }
                
            }
            
        
            
        

        步骤:2

        resources\views\emails

        中为电子邮件 (user-verify.blade.php) 创建刀片视图
            <DOCTYPE html>
            <html lang="en-US">
                 
                <head>
                    <meta charset="utf-8">
                </head>
            
                <body>
                    <p>Dear {{$user->name}},</p>
                    <p>
                        Please click the button below to verify your email address.
                    </p>
            
                    
                    <a href="{{ $actionUrl }}" class="button">{{$actionText}}</a>
                    
                    <p>If you did not create an account, no further action is required.</p>
            
                    <p>
                        Best regards, <br>
                       
                        {{ config('app.name')}}
                    </p>
            
                    <p>
                        <hr>
                        <span class="break-all">
                        <strong>If you’re having trouble clicking the link, copy and paste the URL below into your web browser:</strong><br/>
                        <em>{{$actionUrl}}</em>
                    </p>
            
                    
            
                </body>
            
            </html>
        

        步骤:3

        User model内添加如下方法

        class User extends Authenticatable implements MustVerifyEmail
           {
            use HasFactory, Notifiable;
        
            ...
            ...
            ...
        
            public function sendEmailVerificationNotification()
            {
                $this->notify(new \App\Notifications\UserVerifyNotification(Auth::user()));  //pass the currently logged in user to the notification class
            }
        
        }
        

        说明

        1. 当新用户注册时,Registered 事件 (Illuminate\Auth\Events) 会被调用。
        2. EventServiceProvider(App\Providers\EventServiceProvider))内部有一个监听器,监听Registered事件。 1、注册完成后,调用SendEmailVerificationNotification方法(Illuminate\Auth\Listeners\SendEmailVerificationNotification)。
        3. 监听器(第 2 步)调用库 Illuminate\Auth\Listeners\SendEmailVerificationNotification 中的 sendEmailVerificationNotification() 方法
        4. 我们现在覆盖第 3 步中的 sendEmailVerificationNotification() 函数,并指出我们想使用我们之前在第 1 步中创建的通知类
        5. 通知类获取“验证链接”并调用“用户验证”刀片以发送包含步骤 2 中定义的必要链接的电子邮件
        6. 您需要添加验证所需的路由。只需在 web.php 文件中添加如下路由
            Auth::routes([
                'verify' => true,
                'register' => true,
            ]);
        

        【讨论】:

        • 谢谢你,布鲁夫!发声!
        【解决方案6】:

        基于 Andrew Earls 的回答,您还可以使用以下命令发布应用程序使用的所有降价邮件组件:

        php artisan vendor:publish --tag=laravel-mail

        完成后,您将在 resources/views/vendor/mail 中修改一系列 html 和 markdown 文件。这将允许您修改整体电子邮件布局以及 CSS 的“主题”。我强烈建议好好阅读Mail docs - Customizing The Components

        CSS 主题

        作为一般电子邮件主题快速入门(Laravel 5.7),您可以:

        1. 使用php artisan vendor:publish --tag=laravel-mail 发布主题。
        2. resources/views/vendor/mail/html/themes/default.css 复制到您自己的文件中。例如resources/views/vendor/mail/html/themes/wayne.css
        3. 编辑config/mail.php,在您看到'theme' =&gt; 'default' 的位置将其更改为'theme' =&gt; 'wayne'
        4. 编辑 wayne.css 以重新设置您的电子邮件样式。

        希望对某人有所帮助。

        【讨论】:

          【解决方案7】:

          要发送验证电子邮件,您只需使用下一个代码:

           // send new verification email to user
           $user->sendEmailVerificationNotification();
          

          【讨论】:

            【解决方案8】:

            在路由文件中

            Auth::routes(['verify' => true]);
            

            在 AppServiceProvider.php 文件中

            namespace App\Providers;
            use App\Mail\EmailVerification;
            use Illuminate\Support\ServiceProvider;
            use View;
            use URL;
            use Carbon\Carbon;
            use Config;
            use Illuminate\Auth\Notifications\VerifyEmail;
            use Illuminate\Notifications\Messages\MailMessage;
            
            class AppServiceProvider extends ServiceProvider
            {
                /**
                 * Register any application services.
                 *
                 * @return void
                 */
                public function register()
                {
                    //
                }
            
                /**
                 * Bootstrap any application services.
                 *
                 * @return void
                 */
                public function boot()
                {
                    // Override the email notification for verifying email
                    VerifyEmail::toMailUsing(function ($notifiable){        
                        $verifyUrl = URL::temporarySignedRoute('verification.verify',
                        \Illuminate\Support\Carbon::now()->addMinutes(\Illuminate\Support\Facades 
                        \Config::get('auth.verification.expire', 60)),
                        [
                            'id' => $notifiable->getKey(),
                            'hash' => sha1($notifiable->getEmailForVerification()),
                        ]
                    );
                    return new EmailVerification($verifyUrl, $notifiable);
            
                    });
            
                }
            }
            

            现在使用 Markdown 创建 EmailVerification

            php artisan make:mail EmailVerification --markdown=emails.verify-email
            

            根据需要编辑 EmailVerrification 和刀片文件

            class EmailVerification extends Mailable
            {
                use Queueable, SerializesModels;
                public $verifyUrl;
                protected $user;
                /**
                 * Create a new message instance.
                 *
                 * @return void
                 */
                public function __construct($url,$user)
                {
                    $this->verifyUrl = $url;
                    $this->user = $user;
                }
            
                /**
                 * Build the message.
                 *
                 * @return $this
                 */
                public function build()
                {
                    $address = 'mymail@gmail.com';
                    $name = 'Name';
                    $subject = 'verify Email';
                    return $this->to($this->user)->subject($subject)->from($address, $name)->
                    markdown('emails.verify',['url' => $this->verifyUrl,'user' => $this->user]);
                }
            }
            

            在刀片文件中根据需要更改设计并使用 verifyUrl 显示验证链接并使用 $user 显示用户信息

            谢谢,编码愉快:)

            【讨论】:

              【解决方案9】:

              导航到这些文件

              • vendor/laravel/framework/src/Illuminate/Auth/MustVerifyEmail.php

              • vendor/laravel/framework/src/Illuminate/Auth/Notifications/VerifyEmail.php

              然后自定义它。 你甚至可以在 供应商/laravel/framework/src/Illuminate/Auth/Notifications/VerifyEmail.php 并通过 vendor/laravel/framework/src/Illuminate/Auth/MustVerifyEmail.php 传递值

              例如:

              【讨论】:

              • 永远不要编辑供应商目录文件,世界上最大的错误。
              • 在供应商目录中编辑文件不是一个好主意,因为一旦您通过 composer update 更新依赖项,这些文件就会被覆盖。
              • 当您使用 composer 更新时,供应商将发生变化。切勿尝试在供应商上编辑文件。
              • interface MustVerifyEmail 接口允许您覆盖那里指定的功能。这样您就不必编辑任何/vendor/ 文件。相反,将您喜欢的任何方法从该界面复制到用户模型中,然后复制您需要的供应商文件并将它们粘贴到用户模型中的该函数中...
              猜你喜欢
              • 1970-01-01
              • 2020-07-12
              • 1970-01-01
              • 2019-03-10
              • 2019-03-05
              • 1970-01-01
              • 2019-03-09
              • 1970-01-01
              • 2019-03-05
              相关资源
              最近更新 更多