Skip to content

Instantly share code, notes, and snippets.

@deepak-cotocus
Last active May 7, 2020 11:11
Show Gist options
  • Save deepak-cotocus/aea34065bdfcfe9192f7ae709728583e to your computer and use it in GitHub Desktop.
Save deepak-cotocus/aea34065bdfcfe9192f7ae709728583e to your computer and use it in GitHub Desktop.
Laravel application from scratch

How to develop your first application with full authentication in LARAVEL?

Steps

1. Open git bash in required folder and run below commands to create a laravel project.

composer create-project laravel/laravel Demo-App  "5.5.*" --prefer-dist
composer install
npm install

  • Import Demo-App project to your IDE(I am using Sublime). Your project structure will look like

alt text

  • Open XAMPP Control Panel and start Apache server and mysql Database.
  • Click admin which will redirect you to phpMyAdmin.
  • Create a new database as demo-app

2. Run php artisan make:auth which will create the authentication scaffolding.Make sure that Auth and layout folder has been created under views folder and php Auth::routes(); in web.php file.

3. Let's modify web.php for route call.

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});
Route::get('/sendemail', 'TestController@test')->name('sendemail');
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
Route::get('/user/activation/{token}','Auth\RegisterController@userActivation');

4. Let's work on Controllers

  • Modification needs to be done in LoginController.php and RegisterController.php.

  • No need to modify default Controllers like ForgetPasswordController.php and ResetPasswordController.php

  • Demo-app\app\Http\Controllers\Auth\LoginController.php

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

//Overridden function
    public function showLoginForm()
    {
        return view('login');
    }

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = '/home';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    public function credentials(Request $request){
        $request['is_activated'] = 1;
        return $request->only('email', 'password', 'is_activated');
    }
}
  • Demo-app\app\Http\Controllers\Auth\LoginController.php
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

//Overridden function
    public function showLoginForm()
    {
        return view('login');
    }

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = '/home';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    public function credentials(Request $request){
        $request['is_activated'] = 1;
        return $request->only('email', 'password', 'is_activated');
    }
}
  • Demo-app\app\Http\Controllers\Auth\RegisterController.php
<?php

namespace App\Http\Controllers\Auth;

use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;

use DB;
use Mail;
use Illuminate\Http\Request;
use Illuminate\Auth\Events\Registered;
use App\Mail\UserActivationLinkMail;

use Illuminate\Support\Facades\Log;

class RegisterController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Register Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles the registration of new users as well as their
    | validation and creation. By default this controller uses a trait to
    | provide this functionality without requiring any additional code.
    |
    */

    use RegistersUsers;

    /**
     * Where to redirect users after registration.
     *
     * @var string
     */
    protected $redirectTo = '/home';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest');
    }

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:6|confirmed',
        ]);
    }

    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return \App\User
     */
    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
        ]);
    }

    public function register(Request $request)
    {
        $input = $request->all();
        $validator = $this->validator($input);

        if ($validator->passes()){
            $user = $this->create($input)->toArray(); 
            $user['link'] = str_random(30);

            $emailParams = new \stdClass(); //need to be explored
            $emailParams->usersEmail = $user['email'];
            $emailParams->usersName = $user['name'];
            $emailParams->link = $user['link'];
            $emailParams->subject = "Click activation code to activate account";

            DB::table('users_activations')->insert(['id_user' => $user['id'], 'token' => $user['link']]);
            Mail::to($emailParams->usersEmail)->send(new UserActivationLinkMail($emailParams));

            return redirect()->to('login')->with('Success', "Activation code sent to your email! ");
        }
        return back()->with('Error', $validator->errors());
    }
    
    public function userActivation($token) {
        $check = DB::table('users_activations')->Where('token', $token)->first();
        if (!is_null($check)) {
            $user = User::find($check->id_user);
            if ($user->is_activated == 1){
                return redirect()->to('login')->with('Success', "User is already activated");
            }

            $user->update(['is_activated' => 1]);
            DB::table('users_activations')->where('token', $token)->delete();

            return redirect()->to('password/reset')->with('Success', "user activated successfully");          
        }
        return redirect()->to('login')->with('warning', "your token is invalid");     
    }
}

5. Run below command which will create app/Mail/UserActivationLinkMail.php with below default code.

php artisan make:mail UserActivationLinkMail
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;

class UserActivationLinkMail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('view.name');
    }
}
  • Modify app/Mail/UserActivationLinkMail.php with below code.
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;

use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Config;

class UserActivationLinkMail extends Mailable
{
    use Queueable, SerializesModels;

    private $emailParams;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($params)
    {
        $this->emailParams = $params;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        $this->from(Config::get('app.senderEmail'),Config::get('app.senderName'))
        ->subject($this->emailParams->subject)
        ->view('mail.activation')
        ->with(['emailParams' => $this->emailParams]);
    }
}

6. Add some configuration in .env file and app/config/app.php

  • add couple of line in return statement of app/config/app.php
<?php
return [
    'senderEmail' => env('MAIL_FROM', 'deepak.cotocus@gmail.com'),
    'senderName' => env('MAIL_FROM_NAME', 'Deepak Kumar Gupta'),
    ];
  • Modify .env with below code
APP_NAME='Demo App'
APP_ENV=local
APP_KEY=base64:D+5yE1xacs4pDTFv2A/djbsfWdFa2lFQDFdNBpcpgkU=
APP_DEBUG=true
APP_LOG_LEVEL=debug
APP_URL=http://localhost

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=Demo-app
DB_USERNAME=root
DB_PASSWORD=

BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
SESSION_LIFETIME=120
QUEUE_DRIVER=sync

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=Enter-your-gmailid@gmail.com
MAIL_PASSWORD=enter-your-password
MAIL_ENCRYPTION=tls
MAIL_FROM=deepak.cotocus@gmail.com
MAIL_FROM_NAME=Deepak

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1


7. Modify app/User.php with below code.

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password','is_activated',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
}

8. Demo-App/database/migration

  • By default laravel provide two migration file

    1. 2014_10_12_000000_create_users_table.php
    2. 2014_10_12_100000_create_password_resets_table.php

Run below command to create a migration file php artisan make:migration create_2020_04_29_083104_create_users_activations_table_table

9. Run below command to Migrate above tabels to demo-app database

php artisan migrate

10. Let's work on views

  • Our Views folder will have below structure alt text

  • Demo-app\resources\views\layouts\app.blade.php

<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Demo App') }}</title>

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
    <div id="app">
        <nav class="navbar navbar-expand-md bg-dark navbar-dark">

                <a class="navbar-brand" href="{{ url('/') }}">
                    {{ config('app.name') }}
                </a>

                <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
                    <span class="navbar-toggler-icon"></span>
                </button> 

                <div class="collapse navbar-collapse" id="collapsibleNavbar">                 
                    <!-- Right Side Of Navbar -->
                    <ul class="navbar-nav navbar-right">
                        <!-- Authentication Links -->
                        @guest
                        <li class="nav-item"><a class="nav-link" href="{{ route('login') }}">Login</a></li>
                        <li class="nav-item"><a class="nav-link" href="{{ route('register') }}">Register</a></li>
                        @else
                        <li class="dropdown">
                            <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false" aria-haspopup="true" v-pre>
                                {{ Auth::user()->name }} <span class="caret"></span>
                            </a>

                            <ul class="dropdown-menu">
                                <li>
                                    <a href="{{ route('logout') }}"
                                    onclick="event.preventDefault();
                                    document.getElementById('logout-form').submit();">
                                    Logout
                                    </a>

                                    <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
                                    {{ csrf_field() }}
                                    </form>
                                </li>
                            </ul>
                        </li>
                        @endguest
                    </ul>   
                </div>  
        </nav>
        @yield('content')
    </div>

<!-- Scripts -->
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>
  • Demo-app\resources\views\welcome.blade.php
<!doctype html>
<!-- The lang attribute specifies the language of the element's content. -->
<html lang="{{ app()->getLocale() }}"> 
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Laravel</title>

        <!-- Fonts -->
        <link href="https://fonts.googleapis.com/css?family=Raleway:100,600" rel="stylesheet" type="text/css">

        <!-- Styles -->
        <style>
            html, body {
                background-color: #fff;
                color: #636b6f;
                font-family: 'Raleway', sans-serif;
                font-weight: 100;
                height: 100vh;
                margin: 0;
            }

            .full-height {
                height: 100vh;
            }

            .flex-center {
                align-items: center;
                display: flex;
                justify-content: center;
            }

            .position-ref {
                position: relative;
            }

            .top-right {
                position: absolute;
                right: 10px;
                top: 18px;
            }

            .content {
                text-align: center;
            }

            .title {
                font-size: 84px;
            }

            .links > a {
                color: #636b6f;
                padding: 0 25px;
                font-size: 12px;
                font-weight: 600;
                letter-spacing: .1rem;
                text-decoration: none;
                text-transform: uppercase;
            }

            .m-b-md {
                margin-bottom: 30px;
            }
        </style>
    </head>
    <body>
        <div class="flex-center position-ref full-height">
            @if (Route::has('login'))
                <div class="top-right links">
                    @auth   <!-- to check the current user is authenticated or not -->
                        <a href="{{ url('/home') }}">Home</a>
                    @else
                        <a href="{{ route('login') }}">Login</a>
                        <a href="{{ route('register') }}">Register</a>
                    @endauth
                </div>
            @endif  

            <div class="content">
                <div class="title m-b-md">
                    Demo App
                </div>
            </div>
        </div>
    </body>
</html>
  • Demo-app\resources\views\login.blade.php
@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-12 col-lg-4">
            <div class="card mt-4">
                <div class="card-body">
                    <h2>Login</h2>
                    <form method="POST" action="{{ route('login') }}">
                        {{ csrf_field() }}

                        @if ($message = Session::get('Success'))
                            <div class="alert alert-success">
                                <p>{{ $message }}</p>
                            </div>
                        @endif

                        @if ($message = Session::get('warning'))
                            <div class="alert alert-success">
                                <p>{{ $message }}</p>
                            </div>
                        @endif

                        <div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
                            <label for="email">Email:</label>
                            <input id="email" type="email" class="form-control" placeholder="Enter email" name="email" required>

                            <!-- $errors is a globle variable in Session Class -->

                            @if ($errors->has('email')) 
                                    <span class="help-block">
                                        <strong>{{ $errors->first('email') }}</strong>
                                    </span>
                                @endif

                        </div>


                        <div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">

                            <label for="password">Password</label>
                            <input id="pwd" type="password" class="form-control" name="password" placeholder="Enter password" required>

                                @if ($errors->has('password'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('password') }}</strong>
                                    </span>
                                @endif

                        </div>

                        <div class="form-group form-check">
                            <label class="form-check-label">
                                <input class="form-check-input" type="checkbox" name="remember{{ old('remember') ? 'checked' : '' }}"> Remember me
                            </label>
                        </div>

                        <div class="form-group">
                            <div class="col-md-8 col-md-offset-4">
                                <button type="submit" class="btn btn-primary">
                                    Login
                                </button>

                                <a class="btn btn-link" href="{{ route('password.request') }}">
                                    Forgot Your Password?
                                </a>
                            </div>
                        </div>
                        
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection
  • Demo-app\resources\views\home.blade.php
@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-12 col-lg-4">
            <div class="panel panel-default">
                <div class="panel-heading">Dashboard</div>

                <div class="panel-body">
                    @if (session('status'))
                        <div class="alert alert-success">
                            {{ session('status') }}
                        </div>
                    @endif

                    You are logged in!
                </div>
            </div>
        </div>
    </div>
</div>
@endsection
  • Demo-app\resources\views\auth\register.blade.php
@extends('layouts.app')

@section('content')
<div class="container">  
    <div class="row">
        <div class="col-12 col-lg-6">
            <div class="card mt-4"> 
                <div class="card-body">             

                    <h2>Register</h2>
                    <div>
                        <form class="form-horizontal" method="POST" action="{{ route('register') }}">
                            {{ csrf_field() }}

                            <div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
                                <label for="name" class="col-md-4 control-label">Name</label>

                                <div class="col-md-12">
                                    <input id="name" type="text" class="form-control" name="name" value="{{ old('name') }}" required autofocus>

                                    @if ($errors->has('name'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('name') }}</strong>
                                    </span>
                                    @endif
                                </div>
                            </div>

                            <div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
                                <label for="email" class="col-md-4 control-label">E-Mail Address</label>

                                <div class="col-md-12">
                                    <input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required>

                                    @if ($errors->has('email'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('email') }}</strong>
                                    </span>
                                    @endif
                                </div>
                            </div>
                            <div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
                                <label for="password" class="col-md-4 control-label">Password</label>

                                <div class="col-md-12">
                                    <input id="password" type="password" class="form-control" name="password" required>

                                    @if ($errors->has('password'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('password') }}</strong>
                                    </span>
                                    @endif
                                </div>
                            </div>

                            <div class="form-group">
                                <label for="password-confirm" class="col-md-4 control-label">Confirm Password</label>

                                <div class="col-md-12">
                                    <input id="password-confirm" type="password" class="form-control" name="password_confirmation" required>
                                </div>
                            </div>
                            <div class="form-group">
                                <div class="col-md-6 col-md-offset-4">
                                    <button type="submit" class="btn btn-primary">
                                        Register
                                    </button>
                                </div>
                            </div>
                        </form> 
                    </div>
                </div>
            </div>
        </div> 
    </div>
</div>
@endsection
  • Demo-app\resources\views\mail\activation.blade.php
Welcome, {{ $emailParams->usersName }}
Please activate your account : {{ url('user/activation', $emailParams->link) }}
  • Do not modify Demo-app\resources\views\auth\paswords...

10. Open browser and hit below url and see the magic of laravel and play with your 1st laravel application.

localhost:8000
welcome page will look like alt text


Note

  • Try Login, Register, Reset password and forgot your password
  • Also try email varification feature after successful registration.
  • check is_activated column of Users table before and after the click of activation link.

Check Out for Gmail Email server set up

Downlode Demo-App from Git

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment