简体   繁体   English

如何从 Laravel 5.7 自定义电子邮件验证电子邮件?

[英]How to customize the email verification email from Laravel 5.7?

I just upgraded to Laravel 5.7 and now I am using the built in Email Verification.我刚刚升级到 Laravel 5.7,现在我正在使用内置的电子邮件验证。 However there is 2 things I have not been able to figure out and the primary issue is how can I customize the email that is being sent to the user for verifying their email?但是,有两件事我无法弄清楚,主要问题是如何自定义发送给用户以验证其电子邮件的电子邮件? I also can't figure out how to initiate sending that email if the users changes their email but I can save that for another thread.如果用户更改了他们的电子邮件,我也无法弄清楚如何开始发送​​该电子邮件,但我可以将其保存到另一个线程。

When you want to add Email Verification in Laravel 5.7 the suggested method is to implement Illuminate\\Contracts\\Auth\\MustVerifyEmail and use the Illuminate\\Auth\\MustVerifyEmail trait on the App\\User Model.当你想在Laravel 5.7 中添加电子邮件验证时,建议的方法是实现Illuminate\\Contracts\\Auth\\MustVerifyEmail并在App\\User模型上使用Illuminate\\Auth\\MustVerifyEmail trait。

To make some custom behaviour you can override the method sendEmailVerificationNotification which is the method that notifies the created user by calling the method notify , and passes as a parameter a new instance of the Notifications\\MustVerifyEmail class.要进行一些自定义行为,您可以覆盖方法sendEmailVerificationNotification ,该方法通过调用方法notify创建的用户,并将Notifications\\MustVerifyEmail类的新实例作为参数传递。

You can create a custom Notification which will be passed as a parameter to the $this->notify() within the sendEmailVerificationNotification method in your User Model:您可以创建一个自定义通知,该通知将作为参数传递给用户模型中 sendEmailVerificationNotification 方法中的$this->notify()

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

...then in your CustomVerifyEmail Notification you can define the way the verification will be handled. ...然后在您的CustomVerifyEmail通知中,您可以定义处理验证的方式。 You can notify created user by sending an email with a custom verification.route which will take any parameters that you want.您可以通过发送带有自定义verify.route的电子邮件来通知创建的用户,该电子邮件将采用您想要的任何参数。

Email verification notification process邮件验证通知流程

When a new user signs-up an Illuminate\\Auth\\Events\\Registered Event is emitted in the App\\Http\\Controllers\\Auth\\RegisterController and that Registered event has a listener called Illuminate\\Auth\\Listeners\\SendEmailVerificationNotification which is registered in the App\\Providers\\EventServiceProvider :当新用户Illuminate\\Auth\\Events\\Registered ,在App\\Http\\Controllers\\Auth\\RegisterController发出Illuminate\\Auth\\Events\\Registered事件,并且该Registered事件有一个名为Illuminate\\Auth\\Listeners\\SendEmailVerificationNotification ,该Illuminate\\Auth\\Listeners\\SendEmailVerificationNotification已在App\\Providers\\EventServiceProvider注册App\\Providers\\EventServiceProvider

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

The SendEmailVerificationNotification listener checks if the $user – which is passed as a parameter to new Registered($user = $this->create($request->all())) in the Laravel default authentication App\\Http\\Controllers\\Auth\\RegisterController – is an instance of Illuminate\\Contracts\\Auth\\MustVerifyEmail which is the name of the trait that Laravel suggests is used in the App\\User Model when you want to provide default email verification and also check that $user is not already verified. SendEmailVerificationNotification侦听器检查 $user 是否作为参数传递给 Laravel 默认身份验证App\\Http\\Controllers\\Auth\\RegisterController new Registered($user = $this->create($request->all())) App\\Http\\Controllers\\Auth\\RegisterController – 是Illuminate\\Contracts\\Auth\\MustVerifyEmail一个实例,它是 Laravel 建议在App\\User模型中使用的特征名称,当您想要提供默认电子邮件验证并检查$user是否尚未验证时。 If all that passes, the sendEmailVerificationNotification method is called on that user:如果所有这些都通过了,则会对该用户调用sendEmailVerificationNotification方法:

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

I think the simple way to do this is to make a new notification using the docs here: https://laravel.com/docs/5.7/notifications#creating-notifications我认为这样做的简单方法是使用此处的文档制作新通知: https : //laravel.com/docs/5.7/notifications#creating-notifications

Then override the function:然后覆盖函数:

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

In the users model.在用户模型中。

Or you can或者你可以

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

This will copy the templates to the resources/views/vendor/notifications directory and you can modify them there这会将模板复制到 resources/views/vendor/notifications 目录,您可以在那里修改它们

Unfortunately this email that is sent out is not from a "view", it is a Notification that is built inline actually.不幸的是,发送的这封电子邮件不是来自“视图”,它实际上是内嵌的Notification This is where it is currently built when needing to be sent off: Illuminate\\Auth\\Notifications\\VerifyEmail@toMail .这是当前在需要发送时构建的位置: Illuminate\\Auth\\Notifications\\VerifyEmail@toMail This particular class has a static callback that can be set to build this email instead of letting it do it.这个特定的类有一个静态回调,可以设置它来构建这封电子邮件,而不是让它去做。

In a Service Provider in the boot method you will need to assign a callback for this class:boot方法中的服务提供者中,您需要为此类分配回调:

Something "like" this might work:像这样的东西可能会起作用:

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.'));

    });
}

As this is a notification you should have more options on customizing it.由于这是一条通知,因此您应该有更多自定义选项。

If you want to use your own Notification class you can override the sendEmailVerificationNotification method on the User ( Authenticatable ) model (this is from the MustVerifyEmail trait).如果您想使用自己的Notification类,您可以覆盖User ( Authenticatable ) 模型上的sendEmailVerificationNotification方法(这是来自MustVerifyEmail特征)。

Second Question:第二个问题:

The VerificationController ( App\\Http\\Controllers\\Auth\\VerificationController ) that you should have has a method named resend (from the trait VerifiesEmails ) that looks like a good candidate for this purpose.您应该拥有的VerificationController ( App\\Http\\Controllers\\Auth\\VerificationController ) 有一个名为resend的方法(来自特征VerifiesEmails ),看起来很适合用于此目的。

You should have routes setup for these verification routes via Auth::routes(['verify' => true]);您应该通过Auth::routes(['verify' => true]);为这些验证路由设置路由Auth::routes(['verify' => true]);

Note:笔记:

The verification system uses a field on the users table email_verified_at in 5.7 to mark this.验证系统使用 5.7 中usersemail_verified_at上的一个字段来标记这一点。 You would want to make sure you have this field.你会想确保你有这个字段。 When the user changes email address I suppose you could make this null then redirect them to the resend route, to send off the new verification.当用户更改电子邮件地址时,我想您可以将此设为null然后将它们重定向到resend路由,以发送新的验证。 This will put them into an "unverified" state though until they reverify, if that is what you intend to happen.这会将它们置于“未验证”状态,直到它们重新验证为止,如果这是您打算发生的情况。

Update:更新:

Seems we were going down the right track.看来我们正走在正确的轨道上。 I found this SO answer that goes over similar things:我发现这个 SO 答案涵盖了类似的事情:

Changing the default “subject” field for the verification email in laravel 5.7 在 laravel 5.7 中更改验证电子邮件的默认“主题”字段

For quick and easy way:快速简便的方法:

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

It's creating a new file in:它正在创建一个新文件:

\resources\views\vendor\notifications

This is Laravel's email themplate.这是 Laravel 的电子邮件模板。 You can change and customize it.您可以更改和自定义它。

I'll show you how to customize User verification email using custom view from scratch without using any vendor publish我将向您展示如何使用自定义视图从头开始自定义用户验证电子邮件,而无需使用任何供应商发布

Step: 1第1步

Create a new notification UserVerifyNotification class .创建一个新的通知UserVerifyNotification class It should extend the VerifyEmail class from the library Illuminate\\Auth\\Notifications\\VerifyEmail;它应该从库Illuminate\\Auth\\Notifications\\VerifyEmail;扩展VerifyEmail class Illuminate\\Auth\\Notifications\\VerifyEmail;

Code :代码 :

    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 [
                //
            ];
        }
        
    }
    

    

Step:2第2步

Create the blade view for the email ( user-verify.blade.php ) inside resources\\views\\emailsresources\\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>

Step:3步骤:3

Add the following method inside the User modelUser 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
    }

}

Explanation解释

  1. When a new user is registered, the Registered event ( Illuminate\\Auth\\Events ) is called.注册新用户时,会调用Registered事件 ( Illuminate\\Auth\\Events )。
  2. There is a listener inside EventServiceProvider ( App\\Providers\\EventServiceProvider) that listens to the Registered event.EventServiceProvider ( App\\Providers\\EventServiceProvider)一个监听器来监听 Registered 事件。 1. Once registration is completed, it calls SendEmailVerificationNotification method ( Illuminate\\Auth\\Listeners\\SendEmailVerificationNotification ). 1. 注册完成后,调用SendEmailVerificationNotification方法( Illuminate\\Auth\\Listeners\\SendEmailVerificationNotification )。
  3. The listener (step-2) calls the sendEmailVerificationNotification() method from the library Illuminate\\Auth\\Listeners\\SendEmailVerificationNotification侦听器(第 2 步)调用Illuminate\\Auth\\Listeners\\SendEmailVerificationNotification库中的sendEmailVerificationNotification()方法
  4. We now override the sendEmailVerificationNotification() function in Step: 3 and indicate that we would like to use our own notification class which we made earlier in Step: 1我们现在覆盖步骤 3 中的sendEmailVerificationNotification()函数并表明我们希望使用我们之前在步骤 1 中创建的我们自己的通知类
  5. The notification class gets the 'verification link' and calls the 'user-verify' blade to send email with the necessary link as defined in Step: 2通知类获取“验证链接”并调用“用户验证”刀片以发送包含步骤 2 中定义的必要链接的电子邮件
  6. You'll need to add routes required for verification.您需要添加验证所需的路由。 Just add the following route in the web.php file只需在 web.php 文件中添加以下路由
    Auth::routes([
        'verify' => true,
        'register' => true,
    ]);

Building slightly on the answer by Andrew Earls, you can also publish all the markdown mail components used by the application with this command:以 Andrew Earls 的回答为基础,您还可以使用以下命令发布应用程序使用的所有降价邮件组件:

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

Once that's done you'll have a series of html and markdown files to modify in resources/views/vendor/mail .完成后,您将在resources/views/vendor/mail修改一系列 html 和 markdown 文件。 This will allow you to modify the overall email layout and also 'theme' the CSS.这将允许您修改整体电子邮件布局以及“主题”CSS。 I'd highly recommend having a good read of the Mail docs - Customizing The Components .我强烈建议您仔细阅读邮件文档 - 自定义组件

CSS theming CSS 主题

As a general email theming quick-start (Laravel 5.7), you can:作为通用电子邮件主题快速入门(Laravel 5.7),您可以:

  1. Publish the theme with php artisan vendor:publish --tag=laravel-mail .使用php artisan vendor:publish --tag=laravel-mail发布主题。
  2. Copy resources/views/vendor/mail/html/themes/default.css to your own file.resources/views/vendor/mail/html/themes/default.css复制到您自己的文件中。 eg resources/views/vendor/mail/html/themes/wayne.css例如resources/views/vendor/mail/html/themes/wayne.css
  3. Edit config/mail.php and where you see 'theme' => 'default' change it to 'theme' => 'wayne'编辑config/mail.php并在您看到'theme' => 'default'将其更改为'theme' => 'wayne'
  4. Edit wayne.css to restyle your emails.编辑wayne.css以重新设计您的电子邮件。

Hope that helps someone.希望能帮助某人。

To send verification email you can just use the next code:要发送验证电子邮件,您只需使用下一个代码:

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

In Route File在路由文件中

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

In AppServiceProvider.php File在 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);

        });

    }
}

Now Create EmailVerification With Markdown现在使用 Markdown 创建电子邮件验证

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

Edit The EmailVerrification as you want and the blade file根据需要编辑 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]);
    }
}

in the blade file change the design as you want and use verifyUrl to display the verification link and $user to display user information在刀片文件中根据需要更改设计并使用 verifyUrl 显示验证链接和 $user 显示用户信息

thanks, happy coding :)谢谢,快乐编码:)

Navigate to these files导航到这些文件

  • vendor/laravel/framework/src/Illuminate/Auth/MustVerifyEmail.php供应商/laravel/framework/src/Illuminate/Auth/MustVerifyEmail.php

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

and then customize it.然后自定义它。 you can even introduce a constructor in vendor/laravel/framework/src/Illuminate/Auth/Notifications/VerifyEmail.php and pass value through vendor/laravel/framework/src/Illuminate/Auth/MustVerifyEmail.php你甚至可以在 vendor/laravel/framework/src/Illuminate/Auth/Notifications/VerifyEmail.php 中引入一个构造函数,并通过 vendor/laravel/framework/src/Illuminate/Auth/MustVerifyEmail.php 传递值

eg:例如: 创建了我自己的构造函数 利用传递给构造函数的用户数组值 传递构造函数值

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM