perisian tengah
- Perisian tengah global
- Tetapkan perisian tengah kepada laluan
- Kumpulan Perisian Tengah
Pengenalan
Middleware menyediakan mekanisme yang mudah untuk menapis permintaan HTTP yang memasuki aplikasi. Sebagai contoh, Laravel menyertakan perisian tengah yang mengesahkan pengesahan pengguna untuk aplikasi anda. Jika pengguna tidak disahkan, middleware akan mengubah hala pengguna ke antara muka log masuk. Walau bagaimanapun, jika pengguna disahkan, middleware akan membenarkan permintaan kepada aplikasi tersebut.
Sudah tentu, sebagai tambahan kepada pengesahan identiti, middleware tambahan juga boleh ditulis untuk melaksanakan pelbagai tugas. Contohnya: Perisian tengah CORS boleh bertanggungjawab untuk menambah maklumat pengepala yang sesuai kepada semua respons yang meninggalkan perisian perantara pengelogan boleh log semua permintaan yang masuk ke dalam aplikasi.
Laravel datang dengan beberapa perisian tengah, termasuk pengesahan, perlindungan CSRF, dsb. Semua perisian tengah ini terletak dalam direktori
app/Http/Middleware
.app/Http/Middleware
目录。定义中间件
通过运行
make:middleware
Artisan 命令来创建新的中间件:php artisan make:middleware CheckAge
该命令会在
app/Http/Middleware
目录下创建一个新的CheckAge
类,在这个中间件中,我们仅允许age
参数大于200
的请求对此路由进行访问,否则,将重定向到home
<?php namespace App\Http\Middleware; use Closure;class CheckAge{ /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { if ($request->age <= 200) { return redirect('home'); } return $next($request); } }
正如你所见,假如给定的
age
参数小于或等于200
,这个中间件将返回一个 HTTP 重定向到客户端;否则,请求将进一步传递到应用中。要让请求继续传递到应用程序中(即允许「通过」中间件验证的),只需使用$request
作为参数去调用回调函数$next
。最好将中间件想象为一系列
HTTP
请求,必须经过才能进入你应用的「层」。每一层都会检查请求(是否符合某些条件),(如果不符合)甚至可以(在请求访问你的应用之前)完全拒绝掉。{提示} 所有的中间件都是通过 服务容器,因此,可以在你的中间件的构造函数中键入你需要的任何依赖。
前置 & 后置中间件
中间件是在请求之前或者之后执行,取决于中间件的本身。例如,下面的中间件将在应用处理请求 之前 执行某些任务:
<?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
Tentukan middleware dengan menjalankan perintahmake:middleware
Artisan Untuk mencipta middleware baharu: 🎜// 在 App\Http\Kernel 类中... 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, ];
🎜Arahan ini akan mencipta kelasCheckAge
baharu dalam direktoriapp/Http/Middleware
Dalam perisian tengah ini, kami hanya Membenarkan permintaan dengan < kod>umur parameter yang lebih besar daripada200
untuk mengakses laluan ini, jika tidak, ia akan diubah hala kehome
🎜Route::get('admin/profile', function () { // })->middleware('auth');
🎜Seperti yang anda lihat, jika Memandangkan bahawa Parameterage
kurang daripada atau sama dengan200
, perisian tengah ini akan mengembalikan ubah hala HTTP kepada klien jika tidak, permintaan akan dihantar lebih jauh ke aplikasi. Untuk membenarkan permintaan meneruskan ke aplikasi (iaitu membenarkan perisian tengah untuk "lulus" pengesahan), cuma panggil fungsi panggil balik$next
dengan$request
sebagai parameter. 🎜🎜Sebaik-baiknya menganggap perisian tengah sebagai satu siri permintaanHTTP
yang mesti dilalui untuk sampai ke "lapisan" aplikasi anda. Setiap lapisan menyemak permintaan (jika ia memenuhi syarat tertentu) malah boleh menafikannya sepenuhnya (jika tidak) (sebelum meminta akses kepada aplikasi anda). 🎜🎜{Tip} Semua perisian tengah dihantar melalui bekas perkhidmatan, jadi sebarang kebergantungan yang anda perlukan boleh ditaip dalam pembina perisian tengah anda. 🎜
🎜Pra-& post-middleware
🎜Middleware dilaksanakan sebelum atau selepas permintaan, bergantung pada middleware itu sendiri . Sebagai contoh, perisian tengah berikut akan melaksanakan beberapa tugas sebelum aplikasi mengendalikan permintaan: 🎜Route::get('/', function () { // })->middleware('first', 'second');
🎜 Walau bagaimanapun, perisian tengah ini akan melaksanakan beberapa tugas selepas permintaan aplikasi: 🎜use App\Http\Middleware\CheckAge; Route::get('admin/profile', function () { // })->middleware(CheckAge::class);
🎜 🎜🎜🎜🎜Mendaftar middleware🎜🎜🎜🎜🎜Perisian tengah global
🎜Jika anda mahu perisian tengah dijalankan semasa setiap permintaan HTTP dikendalikan oleh aplikasi anda. Hanya senaraikan perisian tengah ini dalam atribut$middleware
dalamapp/Http/Kernel.php
🎜🎜🎜🎜🎜🎜🎜Tetapkan middleware kepada route
Andaikan anda ingin menetapkan middleware kepada laluan yang ditentukan Pertama, anda harus menetapkan kunci kepada middleware dalam fail
app/Http/Kernel.php
. Secara lalai, perisian tengah terbina dalam Laravel disertakan di bawah atribut$routeMiddleware
dalam kelas ini. Untuk menambah perisian tengah tersuai, hanya tambahkannya pada senarai dan tetapkan kunci tersuai. Contohnya:app/Http/Kernel.php
文件内为该中间件分配一个键。默认情况下,该类中的$routeMiddleware
属性下包含了 Laravel 内置的中间件。若要加入自定义的中间件,只需把它附加到列表后并为其分配一个自定义键。例如:/** * 应用程序的路由中间件组 * * @var array */ protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], 'api' => [ ' throttle:60,1', 'auth:api',], ];
一旦在 HTTP 内核中定义好了中间件,就可以通过
middleware
方法将为路由分配中间件:Route::get('/', function () { // })->middleware('web'); Route::group(['middleware' => ['web']], function () { // });
你也可以为路由分配多个中间件:
/** * 中间件的优先级排序列表 * * 将会强制非全局中间件始终保持给定的顺序。 * * @var array */ protected $middlewarePriority = [ \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\Authenticate::class, \Illuminate\Session\Middleware\AuthenticateSession::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, \Illuminate\Auth\Middleware\Authorize::class,];
分配中间件时,还可以传递完整的类名:
<?php namespace App\Http\Middleware; use Closure;class CheckRole{ /** * 处理传入的参数 * * @param \Illuminate\Http\Request $request * @param \Closure $next * @param string $role * @return mixed */ public function handle($request, Closure $next, $role) { if (! $request->user()->hasRole($role)) { // Redirect... } return $next($request); } }
中间组件
某些时候你可以希望使用一个键把多个中间件打包成一个组,方便将他们应用到路由中去。你可以使用 Http 核心的
$middlewareGroups
属性。Laravel 内置了开箱即用的
web
和api
中间件组,其中包含你可能希望应用于 Web UI 和 API 路由的常用中间件:Route::put('post/{id}', function ($id) { // })->middleware('role:editor');
中间件组可以使用于单个中间件相同的语法分配给路由和控制器操作。同样,中间件使得一次将多个中间件分配给一个路由更加方便:
<?php namespace Illuminate\Session\Middleware; use Closure; class StartSession{ public function handle($request, Closure $next) { return $next($request); } public function terminate($request, $response) { // Store the session data... } }
{提示}
RouteServiceProvider
默认将web
中间件组自动应用到routes/web.php
。Sorting(排序) 中间件
很少情况下,你可能需要中间件以特定的顺序执行,但是当它们被分配到路由时,你无法控制它们的顺序。在这种情况下,可以使用
rrreeeapp/Http/Kernel.php
文件的$middlewarePriority
属性指定中间件优先级:中间件参数
中间件还可以接收其他参数。例如,如果你的应用程序需要在执行给定操作之前验证用户是否为给定的「角色」 ,你可以创建一个
CheckRole
中间件,由它来接收「角色」名称作为附加参数。附加的中间参数应该在
rrreee$next
参数之后传递给中间件:定义路由时通过一个
Setelah middleware ditakrifkan dalam kernel HTTP, anda boleh menetapkan middleware ke laluan melalui kaedah:
rrreeemiddleware
:rrreeeAnda juga boleh menetapkan berbilang middleware ke laluan: rrreee
Apabila memberikan middleware, anda juga boleh menghantar nama kelas penuh:rrreee🎜🎜🎜🎜Komponen tengah🎜 🎜 Kadangkala anda mungkin ingin menggunakan kunci untuk membungkus berbilang perisian tengah ke dalam kumpulan untuk memudahkan penggunaannya pada laluan. Anda boleh menggunakan atribut$middlewareGroups
Http Core. 🎜🎜Laravel mempunyai kumpulan perisian tengahweb
danapi
terbina dalam di luar kotak, yang termasuk perisian tengah biasa yang anda mungkin mahu gunakan pada UI Web dan penghalaan API: 🎜rrreee 🎜 Kumpulan perisian tengah boleh ditugaskan untuk menghala dan tindakan pengawal menggunakan sintaks yang sama seperti perisian tengah individu. Begitu juga, middleware memudahkan untuk memperuntukkan berbilang middleware pada laluan sekaligus: 🎜rrreee🎜{Tip}
🎜🎜🎜RouteServiceProvider
secara automatik menggunakan kumpulan middlewareweb
secara lalai Pergi keroutes/web.php
. 🎜🎜🎜Isih (isih) middleware 🎜🎜Dalam kes yang jarang berlaku, anda mungkin Middleware adalah diperlukan untuk melaksanakan dalam susunan tertentu, tetapi anda tidak mempunyai kawalan ke atas pesanan mereka apabila mereka ditugaskan ke laluan. Dalam kes ini, anda boleh menentukan keutamaan perisian tengah menggunakan atribut$middlewarePriority
bagi failapp/Http/Kernel.php
: 🎜rrreee🎜🎜🎜🎜LearnKu.com🎜. 🎜🎜Parameter perisian tengah
🎜Middleware juga boleh menerima parameter lain. Contohnya, jika aplikasi anda perlu mengesahkan bahawa pengguna ialah "peranan" yang diberikan sebelum melakukan tindakan yang diberikan, anda boleh membuat perisian tengahCheckRole
yang menerima nama "peranan" sebagai parameter tambahan. 🎜🎜Parameter perantaraan tambahan hendaklah dihantar ke middleware selepas parameter$next
: 🎜rrreee🎜Apabila mentakrifkan laluan, lalukan:
untuk memisahkan nama middleware dan parameter. Parameter perisian tengah. Gunakan koma untuk memisahkan berbilang parameter: 🎜rrreee🎜🎜🎜🎜🎜🎜Terminable Middleware
Kadangkala, middleware mungkin perlu melakukan beberapa kerja selepas menyediakan respons HTTP. Sebagai contoh, perisian tengah "sesi" terbina dalam Laravel menulis data sesi ke storan apabila respons sedia sepenuhnya. Jika anda mentakrifkan kaedah
rrreeemenamatkan
pada perisian tengah anda, ia akan dipanggil secara automatik selepas respons sedia untuk dihantar ke penyemak imbas. Kaedahterminate
方法,那么它将会在响应准备发送到浏览器之后自动调用。terminate
方法应该同时接收请求和响应。定义了这个中间件之后,别忘了将它添加到路由列表或者app/Http/Kernel.php
文件的全局中间件中。当你在中间件上调用
terminate
方法的时候, Laravel 将从 服务容器 中解析出一个新的中间件实例。如果在调用handle
和terminate
方法的同时使用相同的中间件实例,请使用容器的singleton
rrreeemenamatkan
harus menerima kedua-dua permintaan dan respons. Selepas mentakrifkan perisian tengah ini, jangan lupa untuk menambahkannya pada senarai laluan atau perisian tengah global dalam failapp/Http/Kernel.php
. Artikel ini pertama kali diterbitkan di laman web