在Laravel中定制身份验证:建立定制警卫
#网络开发人员 #php #laravel #authentication

Laravel警卫用于对用户进行身份验证并控制对应用程序不同部分的访问。警卫是实现后卫接口的类,并负责检查用户的凭据并确定是否应授予对应用程序的访问。
拉维尔(Laravel)与几个警卫一起运送,例如会议后卫和令牌后卫,但您也可以创建自定义后卫以满足您的特定需求。

在本教程中,我将向您展示如何在Laravel中实现自定义警卫,从而创建管理员对Admin仪表板的身份验证的管理员。

1.环境设置

首先,您需要在本地机器或开发环境上安装Laravel。这是您可以用于安装的一些资源

如果您已经在本地计算机上运行了Laravel和Composer,则可以继续创建一个新项目。

composer create-project laravel/laravel example-app

这是一个图像,说明运行的Laravel项目在完成所有安装后的浏览器

Image description

2.创建管理员模型,迁移和控制器

使用一个运行的Laravel项目,下一步是创建管理员模型,迁移和控制器。

管理员模型和迁移:

php artisan make:model Admin -m

上面的代码创建了两个文件,即管理模型和管理员迁移

管理员控制器:

php artisan make:controller AdminController

3.构建迁移的管理表

创建管理员迁移类后,下一步是添加管理表所需的列。您的管理迁移课应该看起来像这样:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('admins', function (Blueprint $table) {
            $table->id();
            $table->string('name')->nullable();
            $table->string('email')->unique();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('admins');
    }
};

现在您需要运行迁移:

php artisan migrate

4.将种子数据到管理表

成功执行迁移后,将在您的数据库中创建一个名为admins的表,我们将不得不将数据播种到表中。

laravel包括使用种子类用数据播种数据库的能力。所有种子类都存储在数据库/播种机目录中。默认情况下,为您定义了一个数据库服务员类。在此类中,您可以使用呼叫方法运行其他种子类,从而可以控制种子顺序。
在Laravel的官方文件中阅读有关Laravel播种的更多信息:
Laravel Database Seeding

管理员:

php artisan make:seed AdminSeeder

上面的代码创建了一个Admin Seeder类,该类将更新为这样:

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use DB;

class AdminSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
         DB::table('admins')->delete();
        $adminRecords = [
            [
                'id'=>1,'name'=>'Nerdy Gedoni','email'=>'superadmin@admin.online','password'=>'$2y$10$IK0Vz4QUjPIRszOIjfRvJO9PlbHB7kY6fRhJGFUIKNdxf.I3iW/ry'
            ]
          ];

          DB::table('admins')->insert($adminRecords);
    }
}

注意:管理密码与Laravel Tinker哈希:hash password with laravel tinker

要使我们的种子工作,我们必须在DatabaseSeeder.php文件中调用我们的AdminSeeder

前往\database\seeder\DatabaseSeeder.php文件,然后以这样的方式致电我们的AdminSeeder

<?php

namespace Database\Seeders;

// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call(AdminSeeder::class);
    }
}

种子数据:

php artisan db:seed

5.创建管理中间件和警卫

laravel包括一个验证应用程序用户的中间件。如果未对用户进行身份验证,则中间件将将用户重定向到您的应用程序的登录屏幕。但是,如果用户经过身份验证,则中间件将允许请求进一步进入应用程序。

创建管理中间件:

php artisan make:middleware Admin

我们的管理员中间件将验证用户(admin)是否经过身份验证。如果不是用户,它将将用户重定向到管理员登录路由。更新您的中间件以使其看起来像这样:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Auth;

class Admin
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
     */
    public function handle(Request $request, Closure $next)
    {
        if (!Auth::guard('admin')->check()) {
            return Redirect('/admin');
        }
        return $next($request);
    }
}

现在转到我们的kernel.php文件app\http\kernel.php并插入管理中间件类:

    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \App\Http\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        'admin' => \App\Http\Middleware\Admin::class,
    ];

接下来,我们必须在我们的config\auth.php文件中创建管理员:

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

        //guard for the admin login
           'admin' => [
            'driver' => 'session',
            'provider' => 'admins', //admin table
        ],
    ],


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

            'admins' => [
            'driver' => 'eloquent',
            'model' => App\Models\Admin::class,
        ],
    ],


6.自定义路线

我们更新的路由routes\web.php看起来像这样:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AdminController;


Route::get('/', function () {
    return view('welcome');
});

Auth::routes();

Route::prefix('/admin')->namespace('Admin')->group(function (){

    Route::get('/', [AdminController::class, 'login']);
    Route::post('login', [AdminController::class, 'loginAdmin'])->name('admin.login');

    Route::group(['middleware'=>['admin']],function ()
    {
        Route::get('dashboard', [AdminController::class, 'dashboard'])->name('admin.dashboard');
        Route::post('logout', [AdminController::class, 'logout'])->name('admin.logout');

    });
});

Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');

7.更新管理员模型和控制器

现在,我们已经完成了web.php文件中的路由,我们将前往管理员模型并将其更新为这样:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
//imported
use Illuminate\Foundation\Auth\User as Authenticatable;

class Admin extends Authenticatable
{
    use HasFactory;

    protected $guard = 'admin';

    protected $fillable = [
        'name',
        'email',
        'password',
        'created_at',
        'updated_at',

    ];

    protected $hidden = [
        'password',
        'remember_token',
    ];

}

最终更新您的addinController:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;
use Auth;

class AdminController extends Controller
{
     public function login(){
        return view('admin.login');
    }

    public function loginAdmin(Request $request){

          if (Auth::guard('admin')->attempt(['email'=>$request['email'], 'password'=>$request['password']])) {
            return Redirect('admin/dashboard')->with('message', 'Logged In Successfully...');
        }
        else{
            return Redirect()->back()->with('message', 'Invalid Login Details');
        }
    }

    public function dashboard()
    {
        return view('admin.dashboard');
    }


    public function logout()
    {
        Auth::guard('admin')->logout();
        return Redirect('/admin')->with('message', 'Logged Out Successfully... ');
    }
}

AdminController有四种方法,loginloginAdmindashboardlogout
login:返回管理员登录视图
loginAdmin:验证并返回管理仪表板
dashboard:返回管理仪表板
logout:登录admin

8.创建登录和仪表板视图

最后,我们将在Thee Views Files Folde18中创建管理登录和管理仪表板。我们的结构应该看起来像这样:

Image description

现在更新相应的视图。

登录:

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- CSRF Token -->
        <meta name="csrf-token" content="{{ csrf_token() }}">
        <title>{{ config('app.name', 'Laravel') }}</title>
        <!-- Fonts -->
        <link rel="dns-prefetch" href="//fonts.gstatic.com">
        <link href="https://fonts.bunny.net/css?family=Nunito" rel="stylesheet">
        <!-- Scripts -->
        @vite(['resources/sass/app.scss', 'resources/js/app.js'])
    </head>
    <body>
        <div id="app">
            <nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
                <div class="container">
                    <a class="navbar-brand" href="{{ url('/') }}">
                        {{ config('app.name', 'Laravel') }}
                    </a>
                    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
                    <span class="navbar-toggler-icon"></span>
                    </button>
                    <div class="collapse navbar-collapse" id="navbarSupportedContent">
                        <!-- Left Side Of Navbar -->
                        <ul class="navbar-nav me-auto">
                        </ul>
                        <!-- Right Side Of Navbar -->
                        <ul class="navbar-nav ms-auto">

                        </ul>
                    </div>
                </div>
            </nav>
            <main class="py-4">
                <div class="container">
                    <div class="row justify-content-center">
                        <div class="col-md-8">
                            <div class="card">
                                <div class="card-header">{{ __('Admin Login') }}</div>
                                <div class="card-body">
                                    <form method="POST" action="{{ route('admin.login') }}">
                                        @csrf
                                        <div class="row mb-3">
                                            <label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>
                                            <div class="col-md-6">
                                                <input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>

                                            </div>
                                        </div>
                                        <div class="row mb-3">
                                            <label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>
                                            <div class="col-md-6">
                                                <input id="password" type="password" class="form-control" name="password" required autocomplete="current-password">

                                            </div>
                                        </div>

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

                                            </div>
                                        </div>
                                    </form>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </main>
        </div>
    </body>
</html>

仪表板:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- CSRF Token -->
        <meta name="csrf-token" content="{{ csrf_token() }}">
        <title>{{ config('app.name', 'Laravel') }}</title>
        <!-- Fonts -->
        <link rel="dns-prefetch" href="//fonts.gstatic.com">
        <link href="https://fonts.bunny.net/css?family=Nunito" rel="stylesheet">
        <!-- Scripts -->
        @vite(['resources/sass/app.scss', 'resources/js/app.js'])
    </head>
    <body>
        <nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
            <div class="container">
                <a class="navbar-brand" href="{{ url('/') }}">
                    {{ config('app.name', 'Laravel') }}
                </a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
                <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <!-- Left Side Of Navbar -->
                    <ul class="navbar-nav me-auto">

                    </ul>
                    <!-- Right Side Of Navbar -->
                    <ul class="navbar-nav ms-auto">
                        <li>
                            <a class="nav-link"href="{{ route('admin.logout') }}"
                                onclick="event.preventDefault();
                                document.getElementById('logout-form').submit();">
                                {{ __('Logout') }}
                            </a>
                            <form id="logout-form" action="{{ route('admin.logout') }}" method="POST" class="d-none">
                                @csrf
                            </form>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
        <main class="py-4">
            <div class="container">
                <div class="row justify-content-center">
                    <div class="col-md-8">
                        <div class="card">
                            <div class="card-header">Welcome Admin!!!</div>
                        </div>
                    </div>
                </div>
            </div>
        </main>
    </body>
</html>

最后,我们完成了。我们刚刚创建了我们的自定义警卫,该警卫验证用户是否已进行身份验证,并在此将已认证的用户导航到我们应用程序的管理部分。

url:localhost\admin
返回身份验证的管理登录页面

Image description

url:localhost\admin\dashboard
用户身份验证后,返回仪表板

Image description

下一个在哪里!

在这个广泛的教程之后,您可能需要深入研究Laravel身份验证,以便以各种可能的方式保护您的应用程序,并实施更复杂的操作

快速链接:
Laravel Documentaion
Authentication

Buy Me A Coffee