One place for hosting & domains

      Easy Node Authentication: Setup and Local

      Note: This article is part of our Easy Node Authentication series.

      Introduction

      Authentication and logins in Node can be a complicated thing. Actually logging in for any application can be a pain. This article series will deal with authenticating in your Node application using the package Passport.

      Note: Updates

      Edit 11/18/2017: Updated to reflect Facebook API changes. Updating dependencies in package.json.
      Edit #1: Changed password hashing to be handled inside user model and asynchronously.
      Edit #2: Changed password hashing to be explicitly called. Helps with future tutorials.

      What we’ll be building:

      We will build an application that will have:

      • Local account logins and signups (using passport-local)
      • Facebook logins and registration (using passport-facebook)
      • Twitter logins and registration (using passport-twitter)
      • Google+ logins and registration (using oauth with passport-google-oauth)
      • Require login for certain routes/sections of your application
      • Creating a password hash for local accounts (using bcrypt-nodejs)
      • Displaying error messages (using flash with connect-flash. required since express 3.x)
      • Linking all social accounts under one user account
      • Allowing a user to unlink a specific social account

      Enough chit-chat. Let’s dive right into a completely blank Node application and build our entire application from scratch.

      Here’s what we’ll be building:

      And after a user has logged in with all their credentials:

      For this article, we’ll be focusing on setup and only local logins and registrations/signups. Since this is the first article and also deals with setting up our application, it will probably be one of the longer ones if not the longest. Sit tight for the duration of your flight.

      Setting Up Our Application

      To set up our base Node application, we’ll need a few things. We’ll set up our npm packages, node application, configuration files, models, and routes.

              - app
              ------ models
              ---------- user.js  <!-- our user model -->
              ------ routes.js    <!-- all the routes for our application -->
              - config
              ------ auth.js      <!-- will hold all our client secret keys (facebook, twitter, google) -->
              ------ database.js  <!-- will hold our database connection settings -->
              ------ passport.js  <!-- configuring the strategies for passport -->
              - views
              ------ index.ejs    <!-- show our home page with login links -->
              ------ login.ejs    <!-- show our login form -->
              ------ signup.ejs   <!-- show our signup form -->
              ------ profile.ejs  <!-- after a user logs in, they will see their profile -->
              - package.json      <!-- handle our npm packages -->
              - server.js         <!-- setup our application -->
      

      Go ahead and create all those files and folders and we’ll fill them in as we go along.

      We are going to install all the packages needed for the entire tutorial series. This means we’ll install all the packages needed for passport local, facebook, twitter, google, and the other things we need. It’s all commented out so you know what each does.

      package.json

          {
            "name": "node-authentication",
            "main": "server.js",
            "dependencies" : {
              "express" : "~4.14.0",
              "ejs" : "~2.5.2",
              "mongoose" : "~4.13.1",
              "passport" : "~0.3.2",
              "passport-local" : "~1.0.0",
              "passport-facebook" : "~2.1.1",
              "passport-twitter" : "~1.0.4",
              "passport-google-oauth" : "~1.0.0",
              "connect-flash" : "~0.1.1",
              "bcrypt-nodejs" : "latest",
      
              "morgan": "~1.7.0",
              "body-parser": "~1.15.2",
              "cookie-parser": "~1.4.3",
              "method-override": "~2.3.6",
              "express-session": "~1.14.1"
            }
          }
      

      Most of these are pretty self-explanatory.

      • Express is the framework.
      • Ejs is the templating engine.
      • Mongoose is object modeling for our MongoDB database.
      • Passport stuff will help us authenticating with different methods.
      • Connect-flash allows for passing session flashdata messages.
      • Bcrypt-nodejs gives us the ability to hash the password.

      I use bcrypt-nodejs instead of bcrypt since it is easier to set up in Windows.

      Now that we have all of our dependencies ready to go, let’s go ahead and install them:

      npm install With all of our packages ready to go, let’s set up our application in server.js.

      Let’s make all our packages work together nicely. Our goal is to set up this file and try to have it bootstrap our entire application. We’d like to not go back into this file if it can be helped. This file will be the glue for our entire application.

      server.js

          
          
          var express  = require('express');
          var app      = express();
          var port     = process.env.PORT || 8080;
          var mongoose = require('mongoose');
          var passport = require('passport');
          var flash    = require('connect-flash');
      
          var morgan       = require('morgan');
          var cookieParser = require('cookie-parser');
          var bodyParser   = require('body-parser');
          var session      = require('express-session');
      
          var configDB = require('./config/database.js');
      
          
          mongoose.connect(configDB.url); 
      
          
      
          
          app.use(morgan('dev')); 
          app.use(cookieParser()); 
          app.use(bodyParser()); 
      
          app.set('view engine', 'ejs'); 
      
          
          app.use(session({ secret: 'ilovescotchscotchyscotchscotch' })); 
          app.use(passport.initialize());
          app.use(passport.session()); 
          app.use(flash()); 
      
          
          require('./app/routes.js')(app, passport); 
      
          
          app.listen(port);
          console.log('The magic happens on port ' + port);
      

      We are going to comment out our passport configuration for now. We’ll uncomment it after we create that config/passport.js file.

      The path of our passport object is important to note here. We will create it at the very beginning of the file with var passport = require('passport');. Then we pass it into our config/passport.js file for it to be configured. Then we pass it to the app/routes.js file for it to be used in our routes.

      Now with this file, we have our application listening on port 8080. All we have to do to start up our server is:

      node server.js Then when we visit http://localhost:8080 we will see our application. (Not really right this moment since we have some more set up to do)

      Auto Refreshing: By default, Node.js doesn’t automatically refresh our server every time we change files. To do that we’ll use nodemon. Just install with: npm install -g nodemon and use with: nodemon server.js.

      Now, this won’t do much for our application since we don’t have our database configuration, routes, user model, or passport configuration set up. Let’s do the database and routes now.

      We already are calling this file in server.js. Now we just have to set it up.

      config/database.js

          module.exports = {
      
              'url' : 'your-settings-here' 
      
          };
      

      Fill this in with your own database. If you don’t have a MongoDB database lying around, I would suggest going to Modulus.io and grabbing one. Once you sign up (and you get a $15 credit for signing up), you can create your database, grab its connection URL, and place it in this file.

      You can also install MongoDB locally and use a local database. You can find instructions here: An Introduction to MongoDB.

      We will keep our routes simple for now. We will have the following routes:

      • Home Page (/)
      • Login Page (/login)
      • Signup Page (/signup)
      • Handle the POST for both login
      • Handle the POST for both signup
      • Profile Page (after logged in)

      app/routes.js

          module.exports = function(app, passport) {
      
              
              
              
              app.get('/', function(req, res) {
                  res.render('index.ejs'); 
              });
      
              
              
              
              
              app.get('/login', function(req, res) {
      
                  
                  res.render('login.ejs', { message: req.flash('loginMessage') });
              });
      
              
              
      
              
              
              
              
              app.get('/signup', function(req, res) {
      
                  
                  res.render('signup.ejs', { message: req.flash('signupMessage') });
              });
      
              
              
      
              
              
              
              
              
              app.get('/profile', isLoggedIn, function(req, res) {
                  res.render('profile.ejs', {
                      user : req.user 
                  });
              });
      
              
              
              
              app.get('/logout', function(req, res) {
                  req.logout();
                  res.redirect('/');
              });
          };
      
          
          function isLoggedIn(req, res, next) {
      
              
              if (req.isAuthenticated())
                  return next();
      
              
              res.redirect('/');
          }
      

      app.post: For now, we will comment out the routes for handling the form POST. We do this since passport isn’t set up yet.

      req.flash: This is the connect-flash way of getting flashdata in the session. We will create the loginMessage inside our passport configuration.

      isLoggedIn: Using route middleware, we can protect the profile section route. A user has to be logged in to access that route. Using the isLoggedIn function, we will kick a user back to the home page if they try to access http://localhost:8080/profile and they are not logged in.

      Logout: We will handle log out by using req.logout() provided by passport. After logging out, redirect the user to the home page.

      With our server running, we can visit our application in our browser athttp://localhost:8080. Once again, we won’t see much since we haven’t made our views. Let’s go do that now. (We’re almost to the authentication stuff, I promise).

      Here we’ll define our views for our home page, login page, and signup/registration page.

      Home Page views/index.ejs

      Our home page will just show links to all our forms of authentication.

      views/index.ejs

          <!doctype html>
          <html>
          <head>
              <title>Node Authentication</title>
              <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css"> 
              <link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css"> 
              <style>
                  body        { padding-top:80px; }
              </style>
          </head>
          <body>
          <div class="container">
      
              <div class="jumbotron text-center">
                  <h1><span class="fa fa-lock"></span> Node Authentication</h1>
      
                  <p>Login or Register with:</p>
      
                  <a href="/login" class="btn btn-default"><span class="fa fa-user"></span> Local Login</a>
                  <a href="/signup" class="btn btn-default"><span class="fa fa-user"></span> Local Signup</a>
              </div>
      
          </div>
          </body>
          </html>
      

      Now if we visit our app in our browser, we’ll have a site that looks like this:

      Here are the views for our login and signup pages also.

      Login Form views/login.ejs

      views/login.ejs

          <!doctype html>
          <html>
          <head>
              <title>Node Authentication</title>
              <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css"> 
              <link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css"> 
              <style>
                  body        { padding-top:80px; }
              </style>
          </head>
          <body>
          <div class="container">
      
          <div class="col-sm-6 col-sm-offset-3">
      
              <h1><span class="fa fa-sign-in"></span> Login</h1>
      
              
              <% if (message.length > 0) { %>
                  <div class="alert alert-danger"><%= message %></div>
              <% } %>
      
              
              <form action="/login" method="post">
                  <div class="form-group">
                      <label>Email</label>
                      <input type="text" class="form-control" name="email">
                  </div>
                  <div class="form-group">
                      <label>Password</label>
                      <input type="password" class="form-control" name="password">
                  </div>
      
                  <button type="submit" class="btn btn-warning btn-lg">Login</button>
              </form>
      
              <hr>
      
              <p>Need an account? <a href="/signup">Signup</a></p>
              <p>Or go <a href="/">home</a>.</p>
      
          </div>
      
          </div>
          </body>
          </html>
      

      Signup Form views/signup.ejs

      views/signup.ejs

          <!doctype html>
          <html>
          <head>
              <title>Node Authentication</title>
              <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css"> 
              <link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css"> 
              <style>
                  body        { padding-top:80px; }
              </style>
          </head>
          <body>
          <div class="container">
      
          <div class="col-sm-6 col-sm-offset-3">
      
              <h1><span class="fa fa-sign-in"></span> Signup</h1>
      
              
              <% if (message.length > 0) { %>
                  <div class="alert alert-danger"><%= message %></div>
              <% } %>
      
              
              <form action="/signup" method="post">
                  <div class="form-group">
                      <label>Email</label>
                      <input type="text" class="form-control" name="email">
                  </div>
                  <div class="form-group">
                      <label>Password</label>
                      <input type="password" class="form-control" name="password">
                  </div>
      
                  <button type="submit" class="btn btn-warning btn-lg">Signup</button>
              </form>
      
              <hr>
      
              <p>Already have an account? <a href="/login">Login</a></p>
              <p>Or go <a href="/">home</a>.</p>
      
          </div>
      
          </div>
          </body>
          </html>
      

      Authenticating With Passport Locally

      Finally! We have finally set up our application and have gotten to the authentication part. Don’t worry. The rest of the authentication articles in this tutorial series will use the same base so we won’t have to set up our application again.

      So far we have installed our packages, set up our application, connected to our database, created our routes, and created our views.

      Now we will create our user model, configure passport for local authentication, and use our configured passport to process our login/signup forms.

      We will create our user model for the entire tutorial series. Our user will have the ability to be linked to multiple social accounts and to a local account. For local accounts, we will be keeping email and password. For the social accounts, we will be keeping their id, token, and some user information.

      You can change these fields out to be whatever you want. You can authenticate locally using username and password (passport-local actually uses username by default but we’ll change that to email).

      app/models/user.js

          
          var mongoose = require('mongoose');
          var bcrypt   = require('bcrypt-nodejs');
      
          
          var userSchema = mongoose.Schema({
      
              local            : {
                  email        : String,
                  password     : String,
              },
              facebook         : {
                  id           : String,
                  token        : String,
                  name         : String,
                  email        : String
              },
              twitter          : {
                  id           : String,
                  token        : String,
                  displayName  : String,
                  username     : String
              },
              google           : {
                  id           : String,
                  token        : String,
                  email        : String,
                  name         : String
              }
      
          });
      
          
          
          userSchema.methods.generateHash = function(password) {
              return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
          };
      
          
          userSchema.methods.validPassword = function(password) {
              return bcrypt.compareSync(password, this.local.password);
          };
      
          
          module.exports = mongoose.model('User', userSchema);
      

      Our model is done. We will be hashing our password within our user model before it saves to the database. This means we don’t have to deal with generating the hash ourselves. It is all handled nicely and neatly inside our user model.

      Let’s move on to the important stuff of this article: authenticating locally!

      Configuring Passport for Local Accounts

      All the configuration for passport will be handled in config/passport.js. We want to keep this code in its own file away from our other main files like routes or the server file. I have seen some implementations where passport will be configured in random places. I believe having it in this config file will keep your overall application clean and concise.

      So far, we have created our passport object in server.js, and then we pass it to our config/passport.js file. This is where we configure our Strategy for local, facebook, twitter, and google. This is also the file where we will create the serializeUser and deserializeUser functions to store our user in session.

      I would highly recommend going to read the passport docs to understand more about how the package works.

      We will be handling login and signup in config/passport.js. Let’s look at signup first.

      config/passport.js

          
          var LocalStrategy   = require('passport-local').Strategy;
      
          
          var User            = require('../app/models/user');
      
          
          module.exports = function(passport) {
      
              
              
              
              
              
      
              
              passport.serializeUser(function(user, done) {
                  done(null, user.id);
              });
      
              
              passport.deserializeUser(function(id, done) {
                  User.findById(id, function(err, user) {
                      done(err, user);
                  });
              });
      
              
              
              
              
              
      
              passport.use('local-signup', new LocalStrategy({
                  
                  usernameField : 'email',
                  passwordField : 'password',
                  passReqToCallback : true 
              },
              function(req, email, password, done) {
      
                  
                  
                  process.nextTick(function() {
      
                  
                  
                  User.findOne({ 'local.email' :  email }, function(err, user) {
                      
                      if (err)
                          return done(err);
      
                      
                      if (user) {
                          return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
                      } else {
      
                          
                          
                          var newUser            = new User();
      
                          
                          newUser.local.email    = email;
                          newUser.local.password = newUser.generateHash(password);
      
                          
                          newUser.save(function(err) {
                              if (err)
                                  throw err;
                              return done(null, newUser);
                          });
                      }
      
                  });
      
                  });
      
              }));
      
          };
      

      We have now provided a strategy to passport called local-signup. We will use this strategy to process our signup form. Let’s open up our app/routes.js and handle the POST for our signup form.

      app/routes.js

          ...
      
              
              app.post('/signup', passport.authenticate('local-signup', {
                  successRedirect : '/profile', 
                  failureRedirect : '/signup', 
                  failureFlash : true 
              }));
      
          ...
      

      That’s all the code we need for the route. All of the heavy-duty stuff lives inside of config/passport.js. All we have to set here is where our failures and successes get redirected. Super clean.

      There is also much more you can do with this. Instead of specifying a successRedirect, you could use a callback and take more control over how your application works. Here is a great stackoverflow answer on error handling. It explains how to use done() and how to be more specific with your handling of a route.

      Testing Signup

      With our passport config finally laid out, we can uncomment that line in our server.js. This will load our config and then we can use our signup form.

      server.js

          ...
      
              
              require('./config/passport')(passport); 
      
          ...
      

      Now that we have passport, our routes, and our redirects in place, let’s go ahead and test our signup form. In your browser, go to http://localhost:8080/signup and fill out your form.

      If all goes according to plan, you should be logged in, your user saved in the session, and you are redirected to the /profile page (the profile page will show nothing right now since we haven’t defined that view).

      If we look in our database, we’ll also see our user sitting there cozily with all the credentials we created for him.

      Exploring Your Database: I use Robomongo to see what’s in my database. Just download it and connect to your database to see your new users after they signup!

      With users able to sign up, let’s give them a way to log in.

      This will be very similar to the signup strategy. We’ll add the strategy to our config/passport.js and the route in app/routes.js.

      config/passport.js

          ...
      
              
              
              
              
              
      
              passport.use('local-login', new LocalStrategy({
                  
                  usernameField : 'email',
                  passwordField : 'password',
                  passReqToCallback : true 
              },
              function(req, email, password, done) { 
      
                  
                  
                  User.findOne({ 'local.email' :  email }, function(err, user) {
                      
                      if (err)
                          return done(err);
      
                      
                      if (!user)
                          return done(null, false, req.flash('loginMessage', 'No user found.')); 
      
                      
                      if (!user.validPassword(password))
                          return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); 
      
                      
                      return done(null, user);
                  });
      
              }));
      
          };
      

      We have now provided a strategy to passport called local-login. We will use this strategy to process our login form. We can check if a user exists, if the password is wrong, and set flash data to show error messages. Let’s open up our app/routes.js and handle the POST for our login form.

      app/routes.js

          ...
      
              // process the login form
              app.post('/login', passport.authenticate('local-login', {
                  successRedirect : '/profile', // redirect to the secure profile section
                  failureRedirect : '/login', // redirect back to the signup page if there is an error
                  failureFlash : true // allow flash messages
              }));
      
          ...
      

      If you try to log in with a user email that doesn’t exist in our database, you will see the error. The same goes for if your password is wrong.

      Now we have functional signup and login forms. If a user is successful in authenticating they will be redirected to the profile page. If they are not successful, they will go home. The last thing we need to do is make our profile page so that those that are lucky enough to signup (all of us?) will have an exclusive place of our site all to themselves.

      views/profile.ejs

          <!doctype html>
          <html>
          <head>
              <title>Node Authentication</title>
              <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css">
              <link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css">
              <style>
                  body        { padding-top:80px; word-wrap:break-word; }
              </style>
          </head>
          <body>
          <div class="container">
      
              <div class="page-header text-center">
                  <h1><span class="fa fa-anchor"></span> Profile Page</h1>
                  <a href="/logout" class="btn btn-default btn-sm">Logout</a>
              </div>
      
              <div class="row">
      
                  
                  <div class="col-sm-6">
                      <div class="well">
                          <h3><span class="fa fa-user"></span> Local</h3>
      
                              <p>
                                  <strong>id</strong>: <%= user._id %><br>
                                  <strong>email</strong>: <%= user.local.email %><br>
                                  <strong>password</strong>: <%= user.local.password %>
                              </p>
      
                      </div>
                  </div>
      
              </div>
      
          </div>
          </body>
          </html>
      

      After a user logs in, they can see all their information. It is grabbed from the session and passed to our view in the app/routes.js file. We will also provide a link to log out.

      There you have it! We’ve built a brand new application from scratch and have the ability to let users signup/register and log in. We even have support for flash messages, hashing passwords, and requiring a login for some sections of our site using route middleware.

      Coming up next we’ll be looking at how to take this same structure, and use passport to authenticate with Facebook, Twitter, and Google. After that, we’ll look at how we can get all these things working together in the same application. Users will be able to log in with one type of account, and then link their other accounts.

      As always, if you see any ways to improve this or need any clarification, sound off in the comments and we’ll respond pretty close to immediately… pretty close.

      Easy and Fast Emails with Laravel 5.3 Mailables

      Introduction

      Laravel 5.3 has just been released and there are a ton of great new features. One of the major improvements is in how you send mail in your applications.

      Let’s take a look at sending emails. Before Laravel 5.3, sending emails in Laravel looked a lot like this.

      Mail::send('emails.send', ['title' => $title, 'message' => $message], function ($message)
       {
          $message->from('[email protected]', 'Bat Signal');
          $message->to('[email protected]');
      });
      

      This method worked for a while, but after sending a couple of emails, the codebase got messy. Since I didn’t really like this method, I found myself using event listeners to build emails.

      At the time of this article, installing Laravel 5.3 with Laravel installer is as simple as.

      1. laravel new project

      Mailables in Laravel abstracts building emails with a mailable class. Basically, mailables are responsible for collating data and passing them to views. Meanwhile, the API for sending emails got really simple.

      To send emails in Laravel, all we have to do now is.

      Mail::to('[email protected]')->send(new KryptoniteFound);
      

      Don’t get me wrong, the previous API will work just fine (and it will still work in your applications) — it’s just that the Mail API got a whole lot simpler.

      With artisan our super handy Laravel CLI-tool, we can simply create a mailable like this.

      1. php artisan make:mail <NameOfMailable>

      Since our mailable’s name is KryptoniteFound, we can create our mailable using this command.

      1. php artisan make:mail KryptoniteFound

      Creating a laravel 5.3 mailable

      After we’ve created our mailable, in app/mail, we can see our newly created mailable class.

      namespace App\Mail;
      
      use Illuminate\Bus\Queueable;
      use Illuminate\Mail\Mailable;
      use Illuminate\Queue\SerializesModels;
      use Illuminate\Contracts\Queue\ShouldQueue;
      
      class KryptoniteFound extends Mailable
      {
          use Queueable, SerializesModels;
      
          public function __construct()
          {
              
          }
      
          public function build()
          {
              return $this->view('view.name');
          }
      }
      

      The created class should look like the snippet above (comments stripped).

      As we can see, the build method builds the message. For our case, we can replace the view.name with the path to our email view email.kryptonite-found.

      In resources/views create a new blade template in an email folder called kryptonite-found.blade.php.

      Any public property on your mailable class is automatically made available to your view file. So passing data to your views is as simple as making the data public on the mailable class.

      Say for example I wanted to pass the weight of Kryptonite found, all I need to do is expose the total on the mailable like this.

      public $total = 30;
      

      While in our view template, we access the data like a normal variable.

      <h1>Woot Woot!!</h1>
      
      <p>Alfred just found <strong>{{ $total }}lbs</strong> of kryptonite</p>
      

      We can also explicitly set data using the with method.

      public function build()
      {
          return $this->view('emails.kryptonite-found')
                      ->with($key, $value);
      }
      

      To send emails, we will use mailtrap. For other service configurations like Amazon SES, Chris wrote an article on the topic.

      Next, we move to our .env file and configure our mail credentials.

      MAIL_DRIVER="smtp"
      MAIL_HOST="mailtrap.io"
      MAIL_PORT=2525
      MAIL_USERNAME=MAIL_USERNAME
      MAIL_PASSWORD=MAIL_PASSWORD
      MAIL_ENCRYPTION=null
      

      You replace MAIL_USERNAME and MAIL_PASSWORD with your mailtrap details. Using the credentials above won’t work.

      Still, on the issue of configuring mail, we also need to configure the mailers from details. In config/mail.php, look for an array from key and configure the address and name. If you are satisfied with the defaults, you can just leave it. But, under no condition can it be null.

      Adding bcc, cc and the rest can be called on $this in the build method.

      public function build()
      {
          $address = '[email protected]';
          $name = 'Ignore Me';
          $subject = 'Krytonite Found';
      
          return $this->view('emails.kryptonite-found')
                      ->from($address, $name)
                      ->cc($address, $name)
                      ->bcc($address, $name)
                      ->replyTo($address, $name)
                      ->subject($subject);
      }
      

      Previously, our routes were located in app/Http/routes.php, but with this release, routes are now in app/routes. Now we can use routes based on the interface (web, API, or console). For this tutorial, we only need the web.php routes file.

      use App\Mail\KryptoniteFound;
      
      Route::get('/', function () {
          
          Mail::to('[email protected]')->send(new KryptoniteFound);
      
          return view('welcome');
      });
      

      Now, we can start our Laravel server by running the following artisan command.

      1. php artisan serve

      We can trigger an email by visiting http://localhost:8080.

      To queue emails, instead of calling send on the Mail::to, just call the queue method and pass it the mailable.

      Mail::to('[email protected]')->queue(new KryptoniteFound);
      

      Delay Message Queueing

      To delay a queued email, we use the later method. This method takes in two parameters. The first is a DateTime object that represents the time to wait. The second parameter is mailable.

      $when = Carbon\Carbon::now()->addMinutes(10);
      
      Mail::to('[email protected]')->later($when, new KryptoniteFound);
      

      Laravel 5.3 offers a lot of promising features like notifications, OAuth, search, etc. Watch out for them.