Skip to content

Instantly share code, notes, and snippets.

@EduardoSP6
Last active January 18, 2022 13:29
Show Gist options
  • Save EduardoSP6/dc4c233f5780f7f71e464b1d4675d205 to your computer and use it in GitHub Desktop.
Save EduardoSP6/dc4c233f5780f7f71e464b1d4675d205 to your computer and use it in GitHub Desktop.
Custom e-mail verification Laravel 7
Implementação de rotina de verificação da conta de e-mail:
- Criar migração do model User adicionando o campo:
$table->timestamp('email_verified_at')->nullable();
- Implementar a interface MustVerifyEmail no model User;
- O Laravel já possui um listener chamado SendEmailVerificationNotification que é responsavel por enviar
o e-mail quando um usuario é registrado. Ele está relacionado ao evento Auth\Events\Registered.
Então basta invocar o evento no método em que o usuário é cadastrado no sistema.
$user = User::create($data);
event(new Registered($user));
*** Os arquivos abaixos so existirão no projeto se você instalou o laravel/ui e gerou os arquivos
via comando: php artisan ui [bootstrap, vue, react] --auth;
- Auth\VerificationController possui a lógica de envio dos links e e-mail para verificação.
Para registrar as rotas necessárias para o controller, passe a opção verify no metodo Auth::routes.
Auth::routes(['verify' => true]);
- O middleware EnsureEmailIsVerified permite que somente os usuarios com email verificado
acesse as rotas. Basta registrá-lo no Kernel e inserir nas rotas desejadas como 'verified';
- A view de envio do e-mail para verificação está localizada em: resources/views/auth/verify.blade.php.
Você pode alterá-la sem problemas. Se a view não estiver no projeto, verifique se você instalou o pacote laravel/ui.
Você pode criar a view manualmente no mesmo diretório e com mesmo nome que irá funcionar;
- O corpo do email é a classe VerifyEmail, que está associada a trait MustVerifyEmail,
no método sendEmailVerificationNotification. Para customizar, basta sobrescrever o método
no model User e criar sua própria classe de e-mail. Se for o caso, criar também um método para gerar a URL de ativação.
Exemplo:
- Model User:
public function sendEmailVerificationNotification()
{
try {
// Backup your default mailer
$backup = Mail::getSwiftMailer();
// Setup your gmail mailer
$host = env('MAIL_HOST');
$port = env('MAIL_PORT');
$encryption = env('MAIL_ENCRYPTION');
$username = env('MAIL_USERNAME');
$password = env('MAIL_PASSWORD');
$transport = new Swift_SmtpTransport($host, $port, $encryption);
$transport->setUsername($username);
$transport->setPassword($password);
$new_mail = new Swift_Mailer($transport);
// Set the mailer as new_mail
Mail::setSwiftMailer($new_mail);
Mail::to($this->getEmailForVerification())
->send(new VerifyEmail($this));
// Restore your original mailer
Mail::setSwiftMailer($backup);
} catch (\Exception $e) {
\Log::error(get_class($this)."->sendEmailVerificationNotification() Error: "
. $e->getMessage() ." - ". $e->getTraceAsString());
}
}
- Classe VerifyEmail:
<?php
namespace App\Mail;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\URL;
class VerifyEmail extends Mailable
{
use Queueable, SerializesModels;
/**
* @var User
*/
private $user;
public $verificationUrl;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct(User $user)
{
$this->user = $user;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
$this->verificationUrl = $this->verificationUrl();
return $this
->from(env('MAIL_FROM_ADDRESS'), env('MAIL_FROM_NAME'))
->subject(\Lang::get('auth.verify_email_subject'))
->view('emails.verify_email');
}
/**
* Get the verification URL
*
* @return string
*/
private function verificationUrl()
{
return URL::temporarySignedRoute(
'verification.verify',
Carbon::now()->addMinutes(Config::get('auth.verification.expire', 60)),
[
'id' => $this->user->getKey(),
'hash' => sha1($this->user->getEmailForVerification()),
]
);
}
}
- Após implementado, os usuários existentes, após login, serão redirecionados para a view verify.blade.php.
Então teremos que customizá-la para ativação da conta.
- Obs.: Se o layout do e-mail possuir imagens como logo da empresa, etc. Utilizar o inline attachment
juntamente com o asset helper do Laravel pois o provedor bloqueia imagens de URLs desconhecidas.
A solução foi inserir a linha no .env: ASSET_URL=${APP_URL} e inserir o codigo abaixo no arquivo blade do layout:
@if(\Illuminate\Support\Str::contains(env('APP_URL'), 'https'))
<img src="{{$message->embed(asset('images/logo.png'))}}" alt="logo">
@else
<img src="images/logo.png" alt="logo">
@endif
Referência: https://laravel.com/docs/7.x/mail#inline-attachments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment