Sunday, September 19, 2021

Laravel 8 Login with Custom Guard Auth Example

Hello Artisan

In this tutorial i will discuss about Laravel custom login with custom guard. To create this laravel multiple guards authentication setup and login i will use doctors table without user model. We know that Laravel uses User model to create default authentication.

So in this laravel custom guard tutorial we will see how we can setup and create our custom guard and make a custom login and logout system in Laravel. Having finished this Laravel custom guard tutorial you will be able to make laravel multi auth in your application.

Laravel uses web as default guard and auth uses as default auth middleware to check whether a user is logged in or not. We will use our own guard to define custom guard name and will create a custom login and logout system with this guard.

So let's see how we can create login system using guard. I have already created this tutorial for Laravel 5. You can see that. In that tutorial i used User model. So you can read also.

 

Read also : Laravel Multi Auth | Multiple Authentication in Laravel 

 

laravel-8-login-with-custom-guard-example

App\Model\Doctor.php

namespace App\Models;

use Illuminate\Support\Facades\Hash;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;

class Doctor extends Authenticatable
{
    use HasFactory, Notifiable;
    
    protected $guarded = [];

    public function setPasswordAttribute($value)
    {
        $this->attributes['password'] = Hash::make($value);
    }

    public function scopeIsActive($query)
    {
        return $query->where('is_active',1);
    }
}
PHP

 

And in migrations file, paste this below code.

public function up()
{
  Schema::create('doctors', function (Blueprint $table) {
      $table->id();
      $table->string('name');
      $table->string('email',32)->unique();
      $table->string('password',255);
      $table->boolean('is_active')->default(true);
      $table->timestamps();
  });
}
PHP

 

Step 3 : Setup or Create Custom Guard

 

In this step we need to create our custom guard name. So visit config/auth.php and create your own guard name as many as you want.

config/auth.php

return [

    /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option controls the default authentication "guard" and password
    | reset options for your application. You may change these defaults
    | as required, but they're a perfect start for most applications.
    |
    */

    'defaults' => [
        'guard' => 'web',
        'passwords' => 'users',
    ],

    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | here which uses session storage and the Eloquent user provider.
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | Supported: "session", "token"
    |
    */

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'doctor' => [
            'driver' => 'session',
            'provider' => 'doctors',
        ],

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
            'hash' => false,
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | If you have multiple user tables or models you may configure multiple
    | sources which represent each model / table. These sources may then
    | be assigned to any extra authentication guards you have defined.
    |
    | Supported: "database", "eloquent"
    |
    */

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],
        'doctors' => [
            'driver' => 'eloquent',
            'model' => App\Models\Doctor::class,
        ],

        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Resetting Passwords
    |--------------------------------------------------------------------------
    |
    | You may specify multiple password reset configurations if you have more
    | than one user table or model in the application and you want to have
    | separate password reset settings based on the specific user types.
    |
    | The expire time is the number of minutes that the reset token should be
    | considered valid. This security feature keeps tokens short-lived so
    | they have less time to be guessed. You may change this as needed.
    |
    */

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
            'throttle' => 60,
        ],
        'doctors' => [
            'provider' => 'doctors',
            'table' => 'password_resets',
            'expire' => 60,
            'throttle' => 60,
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Password Confirmation Timeout
    |--------------------------------------------------------------------------
    |
    | Here you may define the amount of seconds before a password confirmation
    | times out and the user is prompted to re-enter their password via the
    | confirmation screen. By default, the timeout lasts for three hours.
    |
    */

    'password_timeout' => 10800,

];
PHP

 

Step 4:  Create Route

 

Now in this step we have to create our route for create Laravel multi auth using guard. Let's create our route.

routes/doctor.php

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Doctor\Auth\LoginController;


Route::name('doctor.')->namespace('Doctor')->prefix('doctor')->group(function(){

    Route::namespace('Auth')->middleware('guest:doctor')->group(function(){
        //login route
        Route::get('/login','LoginController@login')->name('login');
        Route::post('/login','LoginController@processLogin');
    });

    Route::namespace('Auth')->middleware('auth:doctor')->group(function(){

        Route::post('/logout',function(){
            Auth::guard('doctor')->logout();
            return redirect()->action([
                LoginController::class,
                'login'
            ]);
        })->name('logout');

    });

});
PHP

 

Now we have to define our custom route path from route service provider. So change it like below.

namespace App\Providers;

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;

class RouteServiceProvider extends ServiceProvider
{
 
    public const HOME = '/home';

    public const DOCTOR = '/doctor/home';

    protected $namespace = 'App\\Http\\Controllers';

    public function boot()
    {
        $this->configureRateLimiting();

        $this->routes(function () {
            Route::prefix('api')
                ->middleware('api')
                ->namespace($this->namespace)
                ->group(base_path('routes/api.php'));

            Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/web.php'));

           //our custom route path
            Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/doctor.php'));
        });
    }

    protected function configureRateLimiting()
    {
        RateLimiter::for('api', function (Request $request) {
            return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
        });
    }
}
PHP

 

Step 5: Create Controller

Now in this step you have to create our login controller and method which are defined in doctor.php route. So let's create those method.

App\Http\Controllers\Doctor\Auth\LoginController.php

namespace App\Http\Controllers\Doctor\Auth;

use Illuminate\Http\Request;
use Facades\App\Helper\Helper;
use App\Http\Requests\LoginRequest;
use App\Http\Controllers\Controller;
use App\Models\Doctor;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\View;
use App\Providers\RouteServiceProvider;
use Symfony\Component\HttpFoundation\Response;

class LoginController extends Controller
{   
    public function login()
    {
        if(View::exists('doctor.auth.login'))
        {
            return view('doctor.auth.login');
        }
        abort(Response::HTTP_NOT_FOUND);
    }

    public function processLogin(Request $request)
    {   
        $credentials = $request->except(['_token']);
        
        if(isDoctorActive($request->email))
        {
            if(Auth::guard('doctor')->attempt($credentials))
            {   
                return redirect(RouteServiceProvider::DOCTOR);
            }
            return redirect()->action([
                LoginController::class,
                'login'
            ])->with('message','Credentials not matced in our records!');
        }
        return redirect()->action([
            LoginController::class,
            'login'
        ])->with('message','You are not an active doctors!');
    }
}
PHP

 

Now paste this in your helper.php file.

app\helper.php

use App\Models\Doctor;

if(!function_exists('isDoctorActive'))
{
    function isDoctorActive($email) : bool
    {   
        $doctor = Doctor::whereEmail($email)->IsActive()->exists();

        if($doctor)
        {
            return true;
        }
        return false;
    }
}
PHP

 

Now almost all are set to. We have to just create our blade view. 

Step 6: Create Blade

Now just paste this html code in this following path to create login system in Laravel using custom guard.

resources/views/doctor/auth/login.blade.php


@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Doctor Login') }}</div>
                @if(session()->has('message'))
                    <span>{{ session()->get('message') }}</span>
                @endif
                <div class="card-body">
                    <form method="POST" action="{{ route('doctor.login') }}">
                        @csrf

                        <div class="form-group row">
                            <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>

                            <div class="col-md-6">
                                <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>

                                @error('email')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row">
                            <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>

                            <div class="col-md-6">
                                <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">

                                @error('password')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>

                        <div class="form-group row">
                            <div class="col-md-6 offset-md-4">
                                <div class="form-check">
                                    <input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>

                                    <label class="form-check-label" for="remember">
                                        {{ __('Remember Me') }}
                                    </label>
                                </div>
                            </div>
                        </div>

                        <div class="form-group row mb-0">
                            <div class="col-md-8 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Login') }}
                                </button>

                                @if (Route::has('password.request'))
                                    <a class="btn btn-link" href="{{ route('password.request') }}">
                                        {{ __('Forgot Your Password?') }}
                                    </a>
                                @endif
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection
 
HTML

 

for logout, use this route and form


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

<form id="logout-form" action="{{ route('doctor.logout') }}" method="POST" class="d-none">
   @csrf
</form> 
HTML

 

Hope you have understand this example tutorial. You can create as many guard as you want from config/auth.php and have to make login system using those custom guard. You can use User model or you can use other model. It doesn't matter.


Link: https://www.codecheef.org/article/laravel-8-login-with-custom-guard-example 



Laravel transaction middleware


Here's what this looks like:

use Illuminate\Support\Facades\DB;

class WrapRequestInDatabaseTransaction
{
    public function handle($request, Closure $next)
    {
        DB::beginTransaction();

        $response = $next($request);

        if ($response->exception) {
            DB::rollBack();
            return $response;
        }

        DB::commit();

        return $response;
    }
}

Generate and Save Barcode In Your PHP Laravel Application

Hello devs in this brand new example tutorial i am going to show you how to generate and save barcode in you php laravel application. There are many packages for generating barcode in php laravel. 

In this laravel barcode generator example tutorial i won't use milon/barcode package rather i will use /php-barcode-generator package. This package do not support any 2D barcodes, like QR codes. But this package is pretty good for generate barcode. 

Using this php barcode generator with text package you can generate multitype barcode like png, svg, gpg or html text also. In this barcode generator laravel 8 tutorial i will show you step by step and also show you how you can store it into database and how to print that barcode.

 

Laravel 8 barcode generator example

laravel-barcode-generation-example

 

Step 1 : Install picqer/php-barcode-generator Package

In this step we have to install picqer/php-barcode-generator package to create php barcode generator laravel. Run below command to install it.

composer require picqer/php-barcode-generator
PHP

 

Step 2 : Save Barcode

In this step we need to save barcode into database for our product. In this step we will generate barcode for our product and then we will save this barcode image into database. 

Now to generate and save barcode in your php laravel application, follow the below code

$product = new Product;

$number = $request->sku;
$generator = new Picqer\Barcode\BarcodeGeneratorPNG();
$barcode = '< img src="data:image/png;base64,' . base64_encode($generator->getBarcode($number, $generator::TYPE_CODE_128)) . '" >';

$product->barcode = $barcode;
$product->save(); 
PHP

 

Recommended : Avoid Mass Assignment to Set Unguard Globally For Every Model In Laravel

 

In the above code i have use png formatted barcode, but you can use html for your barcode, like

$product = new Product;

$number = $request->sku;
$generator = new Picqer\Barcode\BarcodeGeneratorHTML();
$barcode = $generator->getBarcode($number, $generator::TYPE_CODE_128);

$product->barcode = $barcode;
$product->save();
PHP

 

Hope it can help you to generate and save barcode for your product in your php laravel application.

Link: https://www.codecheef.org/article/generate-and-save-barcode-in-your-php-laravel-application

Tuesday, September 7, 2021

Set Up Virtual Host for cakephp

Open the httpd-vhosts.conf file from the C:/xampp/apacheconf/extra in order to set up new virtual host that can run your CakePHP application. You will have to add the following lines in order to run the application:

<strong>NameVirtualHost *:80
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot C:/xampp/htdocs/jack
ServerName local.jack.com

<Directory “C:/xampp/htdocs/jack”>
Options Indexes FollowSymLinks Includes ExecCGI
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost></strong>

<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot C:/xampp/htdocs/xampp
ServerName localhost
<Directory “C:/xampp/htdocs/xampp”>
Options Indexes FollowSymLinks Includes ExecCGI
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>```

The httpd-vhosts.conf file will have the aforementioned configuration for virtual host to run CakePHP and other php application. I have decided to choose local.jack.com as the server name, and likewise, we will have to add it to the C:/Windows/System32/drivers/etchosts file as mentioned below:

# localhost name resolution is handled within DNS itself.
127.0.0.1 localhost
127.0.0.1 local.jack.com
# ::1 localhost

If your web server is already running, restart it so that you can access the new CakePHP installation by growing to http://local.jack.com through your browser.


Link : https://www.cometchat.com/blog/setup-cakephp-using-xampp-on-windows

 

How to install cakephp on local wamp server?

 1. Download updated Cake PHP from CakePHP Official Website[^] and unzip the file.

2. Copy the folder to Wamp server folder : C:\www\wamp\(cakefolder)
3. Here everything you will have to do in app folder. Don't alter any other folder content, if you don't have much knowledge.
4. Go to (cakefolder) -> app -> Config -> database.php.defult and rename it as database.php
5. Open (cakefoler) -> app -> Config -> core.php and change the Security.salt value and Security.cipherSeed.
6. Make sure the (cakefolder) -> tmp is writable and apache mod_rewrite is enabled.
7. Set the database.php configuration with the database details.
8. Open the browser and type : http://localhost/(cakefolder)/ and that's up.


Thursday, September 2, 2021

Css Loader vs Style Loader Vs Sass-Loader

 The sass-loader will resolve the @import statements and include the imported Sass in the resulting CSS, hence the resulting CSS will probably not have any import statements. But the css-loader does not just handle imports. The three loaders you mention, do very different things and they are meant to be used together, although there are other loaders you could use, which would give a similar result.

  1. sass-loader - Transforms Sass to CSS. (Input: Sass, Output: CSS)
  2. css-loader - Transforms CSS to a JavaScript module. (Input: CSS, Output: JavaScript)
  3. style-loader - Injects the CSS, that is exported by the JavaScript module, into a <style> tag at runtime. (Input: JavaScript, Output: JavaScript).

Note: The output of style-loader is only relevant if you are using CSS modules, which passes on the object that maps class names to local identifiers.