This is a resume about different things (it's for my reference, and you may find it useful), around the implementation of a users registration with email confirmation (laravel examples, and different way of doing, and a resume of some good practice), and more then that about creating your own mail server, using some of the great open source projects. And resuming the concerns of having your own mailing server vs using a cloud service. Also how to send using smtp, and others protocols. so it's about user registration and email servers. [note, i will be updating that through time passing. (i'm not putting all at once)]
You find an implementation in the folder accountEmailConfirmation
It's a direct follow of this online artical tutorial https://phpbits.in/email-verification-with-laravel-5-5/
Note bellow you will find a resume, and some outlines, and important notes. Know that there is more then what in the tutorial, and it can be interesting. i will highlight in bold the very interesting or maybe important things.
We will be using the laravel default auth scaffolding (but follwing the same logic we can use others libraries for that. as laravel-permission by spatie for example).
first we will add to the users table (and so the schema) a new field which is 'verified' we create another table verification_tokens (it will have a direct one to one relation with the users table) [each user will have his unique token] (after setting the migration, and the env config and the database, we can launch the migrate to create the tables)
There the User model and the VerificationToken model. The relationship between the two is a one to one relation. So we will set that. In VerificationToken we create a
user methode, and in the User model, we create a verificationToken methode. both will allow us to set the relationship, and to access one model through the other.
Also we will add
hasVerifiedEmail to the
Note: don't forget to add the tables entries to
fillable property. check it out. And that to avoid a Mass Assignement error. See the resources section bellow to learn about this error.
We add a controller for verification (VerificationController) wich contain a method verify (set user to verified) and another to resend the email (resend).
And we have to overide the methode of the auth registration and login controllers, (registered for registration and authenticated for login). We set it to logout and show the relevant messages and redirect. [after registration we redirect to login page and we show verify your email message. or if wanted we login the user. and we show the message too. not part of the tuto, we can then limit his access. Through checking his status (using conditions in the views. or using a role managment library as laravel-permission for example, and then we will set a role for that state, and associate it to him, and so he will be limited in access)]
For the verification controller, in resend email, we trigger an event for email resend which we would have created, and we have a listener that handle that. we are seeing that next.
Events and there listeners:
There is different ways of implementing that. We will see too another way which is not part of that tuto. but the way in this tuto is through using the events and the listeners, it give a nice way that is flexible. Events let us easily organize the workflow, and the systematic between the different elements.
Here how it's done in the tuto, and it's stright forward. we set two events, one is user registred event. The other is user email resend request event. Then we have a listener that listen to both of those event. Whenever one is triggered, we send the confirmation email to the user through the listener, which will trigger the action. [know that we emit the events, ourselve, in the right place. And in this tuto: It is emited by the use of
UserRegistred event, through
created method of User model, and that is set through the binding using the service provider userRegisteredProvider that we create. (When this function is triggered! the confirmation token will be generated and the the userregistered event is emited right away. [we will come back to this provider in next section] ) ] (check the outline section: we can not to use a serviceProvider, for this even emiting, and implement the same in
registered overided methode in registration auth default controller). For the resend Event, it's emited from within the resend methode of the VerificationController we have created. (it's executed, through a route that we set, and so through a message we show to the user, with the link to resend [that message is shown after you try to login before you are verified (that in the tuto), In this i added this resend also to the message that show after registration, that ask you to check your email.])
Now the event listener. We create it. And let it handle the email sending.
you need to register the events and there listeners. In laravel we do that through the property $listen in the EventServiceProvider. Check it out. Know that in place of creating the Events and Listeners files and the folders manually, you can just register them first, and then with *php artisan Event:generate all files get created for you. (the one already created will be note overided, and only the new one will be added) Know too that you can manually register them, and not through $listen property of EventServiceProvider (see the doc: https://laravel.com/docs/5.6/events#manually-registering-events)
UserCreatedProvider is created, and is used to bind the
created event handling of the user Model. => when the user is created through the handler we provide we generate the verification token and we emit the event UserRegistered, so the listener will send the verification email.
Note: that this is not necessary:
==> option one! is to do that in
registered methode of the registration Auth controller. But with what was done in the tuto, we have the advantage of a better load time. because, the user created event is triggered first and so the
created run before
==> option two! why not just overide it in User model directly. (i'm going to check this out.)
We add the two routes for the verification controller functionalities. One that will run
verify method, and the other for
To send the mail, we will be using laravel Mail system, the
mailable class. we generate it using
php artisan make:mail SendVerificationToken
====> database config:
====> smtp config when using google:
Here is the config when using tls
MAIL_DRIVER=smtp MAIL_HOST=smtp.gmail.com MAIL_PORT=587 [email protected] MAIL_PASSWORD=yourgmailPassword MAIL_ENCRYPTION=tls [email protected] MAIL_FROM_NAME="Allal Mohamed Lamine"
Note if you use ssl instead:
Make sure to check google settings at the time in case they will change the settings. https://support.google.com/mail/answer/7126229?visit_id=1-636588126638512156-915614103&hl=en-GB&rd=1 (may change with time) or through your gmail "settings => frowarding and POP/IMAP" choose "settings instruction".
!!!!! Here a resume of All the process !!!!!
All start at registeration, (we are using laravel default template). Register => and you get the registration form. you enter the registeration data. and you send the form. All that is handled with the default laravel Auth scaffolding. after the registeration finish successefuly, the methode registered, from Auth/RegisterController that overide the one of the default trait used by the auth scaffolding. It's executed. And in this tuto, it's work is to logout and redirect to login with a message to check the email to confirm. (logout because by default, with auth scaffolding after registeration the user is automatically logged in [that behavior can be overided by overiding register methode, the same as with registered] (here a link for that: https://stackoverflow.com/questions/43226145/laravel-5-4-disable-auto-login-after-registration) [you take the code from the trait and just remove
$this->guard()->login($user); and may be modify it to redirect else wher ]. Another link: https://laracasts.com/discuss/channels/laravel/laravel-55-disable-auto-login-after-registration?page=1). Well we droped away. Here we continue. It was registred and it log out and show a message. In the same time (and that as the tuto did) the method created of user. is executed. after user creation. (that was done through the userCreatedServiceProvider, and it's binding of the function). So when that happen it litteraly will generate a verification token for the user. And emit userRegistered event. (Note: created methode get executed before, registered methode. That fact can add a little better load time. Because otherwise we could did all in registered methode [you can have a demo, by switching to the branch "accountEmailConfirmationWithoutUserCreatedProvider" of this repo =>
git checkout accountEmailConfirmationWithoutUserCreatedProvider]). Now we have an event that was emited, so the listener will execute the handle function to handle it. the email verification link is sent to the recipient user. All left is for him to use that link. And that will activate his account (that happen through the corresponding controller (following the used route we set for that). Which will change using the model the verified entry. and that's it). One last lefting for all that. the resend functionality, to resend the verification email again. for that we have a controller. and what it did, is emit resendEvent. which will trigger the listener which will send the email. in the tuto, resend message show only when you try to login and you are not verified yet. You can change that, and add the resend option, for the message stright after registration (that in registered overided methode of the registeration auth controller). So That's the principle, and how things works.
==> we can use other things see the outline bellow [mail servers and configurtation and some different options]
About the implementation above and tuto
-------> creating token in created and not registered
created methode (that is executed when the user is created) to create the token and trigger the UserRegistered event, that will imply sending the mail through the listener handling to the event. Rather
registered method of the registeration auth controller. Give a better load time, because
created get executed first. And
registered just after, we let it handle only the logout and the redirection whith showing the message. And they get executed separatly and asynchrounously.
----> Add resend link to the after registeration and resend messages
Yea! in the tuto The author didn't does that. But it's a good practice. You can't know for sure if your message will be sent. Adding that is great. You can check it out. I did it in this overview. You form a link
'Didn\'t get it? <a href="' . route('auth.verify.resend') . '?email=' . $user->email .'">Resend.</a>');
for example. Also it's good to add it to the message after resend (VerificationController).
Using Google gmail account to send the emails
If you are going to use the smtp server, you need to set the config to .env config file (check it out). But a problem as today you will encounter, is that google will block the tentative to send, because of there new security policy. They have disabled direct smtp operation. And all apps will be blocked. You need to enable allow less secure apps through your gmail settings here a link for that: https://myaccount.google.com/lesssecureapps or by going through "account => sign & security => Apps with account access" you find it all down.
Otherwise you go the secure way, and that throug applying to the oauth2.0 and google policy. (we will treat that later)
----> Note googles offers three ways to send messages, also here is an overview about the sending messages limits
The three methode as now are: G Suite SMTP relay, Gmail SMTP server, Restricted Gmail SMTP server. Here a link that show that, along with the configurations settings: https://support.google.com/a/answer/176600?hl=en
Note: Using gmail as the mailing. Is one of the options that blogger prefer and like to use. But there is the limits to consider. for example for a normal smtp server it's about 2000 messages per day. and 10000 messages per day for gsuite smtp relay. So following the number of the readers that are on the mailing list. That may or not be an option. And you may or not want to follow some strategy. as like using multiple gmail accounts and have a counter to count the sent messages. plus the limit error handling. You can put a mechanism to switch from an account to another. But mostly the right thing is to pay to get the limit up. And use the gsuite smtp relay.
Mail server and the options
to send mails in the end a mail server is needed. Two options come here, setup your own server or use a mail server as a service. Cloud services now a day are too interestings. You can too, use gmail and others mailing platform that allow sending mails through smtp. Even others methods.
Using your own local mail server
One of the options is to implement your own mail server. In a company, they may already have one. In such case you just use there's. But if you want to implement your own mail server. See the section Mail server bellow. You will find all different best options. like using IRedMail for that. And you will find a good overview about mail servers, it's administration, It's construction, and parts. How the tools make it easy. And also why using cloud services that offer that is one of the options. And can be interesting. And why not too.
NOTE: Whatever mail server you are going to use. You need to set the appropriate settings to make sure it works.
Using queue for better performance
We will cover that in the next project. So go see Second section.
Mass Assignement error: don't forget to set the fillable properties of you Model. mysql mariadb length error:
Laravel events and listeners https://laravel.com/docs/5.6/events#manually-registering-events
Laravel mail https://laravel.com/docs/5.6/mail
Laravel Mass assignement error
This against the first methode will have the advantage of a better performance. And a better page loading time.
... to be continued
---- this section is to be comming!
----- this section is to be comming!
list of free open source mail server software not just for php: https://www.how2shout.com/tools/best-free-opensource-mail-server-software.html
Great tuto to see how it work https://www.sitepoint.com/sending-emails-php-phpmailer/
// now this work is in progress! depending in my time.