中间件

中间件提供了一种方便的机制来过滤进入应用程序的 HTTP 请求。例如,Laravel 包含一个验证用户身份的中间件。如果用户未能通过认证,中间件会把用户重定向到登录页面。反之,用户如果通过验证,中间件将把请求进一步转发到应用程序中

定义中间件

通过运行 make:middleware Artisan 命令来创建新的中间件

php artisan make:middleware Auth

前置中间件

在应用处理请求之前执行一些任务

<?php

namespace App\Http\Middleware;

use Closure;

class BeforeMiddleware
{
    public function handle($request, Closure $next)
    {
        // Perform action

        return $next($request);
    }
}

后置中间件

中间件是在应用请求之后执行一些任务

<?php

namespace App\Http\Middleware;

use Closure;

class AfterMiddleware
{
    public function handle($request, Closure $next)
    {
        $response = $next($request);

        // Perform action

        return $response;
    }
}

注册中间件

全局中间件

如果你希望中间件在应用处理每个 HTTP 请求期间运行, 只需要在 app/Http/Kernel.php 中的 $middleware 属性中列出这个中间件。

为路由分配中间件

假设你想为指定的路由分配中间件,首先应该在 app/Http/Kernel.php 文件内为该中间件分配一个键。默认情况下,该类中的 $routeMiddleware 属性下包含了 Laravel 内置的中间件。若要加入自定义的中间件,只需把它附加到列表后并为其分配一个自定义键。例如:

app/Http/Kernel.php
// Within App\Http\Kernel class...

protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];

在HTTP内核中定义了中间件后,可以使用 middleware 方法将中间件分配给路由

Route::get('/profile', function () {
    //
})->middleware('auth');

您还可以将多个中间件分配给路由

Route::get('/', function () {
    //
})->middleware(['first', 'second']);

中间件组

有时,可能希望将多个中间件归为一个键,以使其更易于分配给路由。 您可以使用 HTTP 内核的 $middlewareGroups 属性来实现。

Laravel 开箱即用,带有 web 和 api 中间件组,其中包含您可能要应用于 Web UI 和 API 路由的通用中间件,请记住,这些中间件组由应用程序的 App\Providers\RouteServiceProvider 服务提供商自动应用于相应的 web 和 api 路由文件中的路由

/**
 * The application's route middleware groups.
 *
 * @var array
 */
protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        // \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    'api' => [
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];

示例登录验证中间件

app\Http\Middleware\AuthLogin.php

<?php

namespace App\Http\Middleware;

use App\Models\User\User;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cookie;

class AuthLogin
{
    /**
     * 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)
    {

        // 获取cookie
        $LoginUser = Cookie::get('LoginUser') ? Cookie::get('LoginUser') : '';

        // 因为这里存储的是json数据格式,所以这里需要转成数组
        $LoginUser = json_decode($LoginUser,true);

        // dd($LoginUser);

        // 如果cookie为就要重定向登录页面
        if(empty($LoginUser))
        {
            return redirect('/home/login');
        }

        // 查询该用户是否存在
        $User = User::find($LoginUser['id']);

        if(!$User)
        {
            // 清除cookie
            Cookie::queue(Cookie::forget('LoginUser'));
            // 重定向到登录页面
            return redirect('/home/login');
        }

        // 传值给控制器
        $request->attributes->add(['LoginUser' => $User]);


        return $next($request);
    }
}

app\Http\Kernel.php

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{


    ...

    /**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array<string, class-string|string>
     */
    protected $routeMiddleware = [
        // 新注册的中间件
        'authlogin' => \App\Http\Middleware\AuthLogin::class,
        ...
    ];
}

routes\web.php

<?php

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

/*
|--------------------------------------------------------------------------
| 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('/',[IndexController::class,'index']);


// 需要登录认证
Route::prefix('/home')->middleware('authlogin')->group(function(){
    Route::get('/user',[IndexController::class,'user']);
});


// 不需要登录认证
Route::prefix(('/home'))->group(function(){
    Route::get('/login',[IndexController::class,'login']);
});

app\Http\Controllers\IndexController.php

<?php

namespace App\Http\Controllers;

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

class IndexController extends Controller
{

    // 首页
    public function index()
    {


        return '首页';

    }

    // user
    public function user(Request $request)
    {
        // 获取中间件传的参
        $params = $request->get('LoginUser');

        // 打印
        dump($params);

        return 'user';
    }

    public function login()
    {

        // 用户数据
        $data = [
            'id' => 1,
            'username' => 'admin'
        ];

        // 转成json字符串
        $DataJson = json_encode($data);

        // 设置cookie
        Cookie::queue('LoginUser',$DataJson);

        return 'login';
    }
}
powered by GitbookEdit Time: 2023-04-08 10:28:32