简介#

Laravel 中间件提供了一种方便的机制来过滤进入应用的HTTP请求。例如,Laravel 内置了一个中间件来验证用户的身份认证 ,

如果没有通过身份认证,中间件会将用户重定向到登陆界面,但是,如果用户被认证,中间件将允许该请求进一步进入该应用。

当然,除了身份认证以外,还可以编写另外的中间件来执行各种任务,例如:CORS中间件可以负责为所有离开应用的响应添加合适的头部信息:

日志中间件可以记录所有传入应用的请求。

Laravel 自带了一些中间件,包括身份验证,CSRF 保护等,所有这些中间件都位于

app/Http/Middleware 目录。

定义中间件#

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

php artisan make:middleware CheckAge

该命令将会在app/Http/Middleware 目录内新建一个CheckAge 类。在这个中间件里,我们仅允许提供的参数 age

大于 200  的请求访问该路由。否则 我们将用户重定向到 home .

<?php

namespace App\Http\Middleware;

use Closure;

class CheckAge

{

  /*

    处理传入的请求

    @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)

  {

    //执行动作

    return $next($request);

  }

}

而下面(这种写法的) 中间件会在应用请求之后执行其任务:

<?php

namespace App\Http|Middleware;

use Closre;

class AfterMiddleware

{

  public function handle($request,Closure $next)

{

  $response = $next($request);

  // 执行动作

   return $request;

}

}

注册中间件

全局中间件#

如果你想让中间件在你应用的每个HTTP请求期间运行,只需要在 app/Http/kernel.php 类中的$middleware 属性

里列出这个中间件类。

为路由分配中间件#

如果要为特定的路由分配中间件,首先应该在 app/Http/Kernel.php 文件内为该中间件指定一个键。默认情况下,

Kernel类的$routeMiddleware 属性包含Laravel 内置的中间件条目。要加入自定义的,只需要把它附加到列表后并为其分配一个自定义

键 即可,例如

...

// 在 App\Http\Kernel 类中

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

一旦在kernel中定义了中间件,就可使用middleware方法将中间价分配给路由

Route::get('admin/profile',function(){

  //

})->middleware('auth');

你还可以为路由分配多个中间件:

Route::get('/',function(){

  //

})->middleware('first','second');

分配中间件时,你还可以传递完整的类型:

use App\Http\Middleware\CheckAge;

Route::get('admin/profile',function(){

  //

})->middleware(CheckAge::class);

中间件组#

有时你可能想用单一的 键 为几个中间件分组。使其更容易分配到路由。可以使用Kernel类的$middlewareGroups 属性来实现。

Laravel 自带的web 和 api 中间件组包含了你可能会应用到Web UI 和 API 路由的常见的中间件:

/**
* 应用程序的路由中间件组
*
* @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',
],
];
可以使用与单个中间件相同的语法将中间件组分配给路由和控制器操作,重申一遍,中间件组只是更方便的实现了一次为路由分配多个中间件
Route::get('/',function(){
  //
})->midlleware('web'); Route::group(['middleware'=>['web']],function(){
  //
}) 中间件参数#
中间件也可以接受额外的参数,例如,如果应用需要在运行特定操作前验证经过身份认证的用户是否具备给定的 角色 你可以新建一个 CleckRole
中间件,由它来接收 角色 名称作为附加参数。
附加的中间件参数应该在 $next 参数之后被传递:
<?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)) {
// 重定向...
} return $next($request);
} }
定义路由时通过一个: 来隔开中间名称和参数来指定中间件参数,多个参数就使用逗号分隔:
Route::put('post/{id}',function($id)
{
  //
})->middleware('role:editor');
Terminable 中间件#
有时中间件可能需要在HTTP响应发送到浏览器之后处理一些工作。比如,Laravel 内置对的 [session] 中间件会在响应发送到
浏览器之后将会话数据写入存储器中,如果你在中间件中定义一个 terminate 方法,则会在响应发送到浏览器后自动调用:
<?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...
}
} terminate 方法应该同时接收和响应,一旦定义了这个中间件,你应该将它添加到路由列表
或 app/Http/Kernel.php 文件的全局中间件中。
在你的中间件上调用terninate调用时,Laravel会从服务容器中解析
一个新的中间件实例,如果要在调用 handle和terminate 方法时
使用同一个中间件实例,就使用容器的singleton方法向容器注册中间件。

laravel 的路由中间件的更多相关文章

  1. laravel的路由分组,中间件,命名空间,子域名,路由前缀

    laravel的路由分组,就是把一些具有相同特征的路由进行分组,比如一些路由需要进行验证,一些路由有共同的前缀,一些路由有相同的控制器命名空间等. 这样把路由组合在一起,方便管理,维护性更好. Rou ...

  2. Laravel中路由怎么写(二)

    1.路由命名——给路由起个名字 1.1 基本使用 我们使用as关键字来为路由命名: Route::get('/hello/Laravel',['as'=>'academy',function() ...

  3. laravel 配置路由 api和web定义的路由的区别详解

    1.路由经过中间件方面不同 打开kerenl.php就可以看到区别 protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware ...

  4. [PHP] - Laravel - Route路由

    前言 这里使用的是Laravel 5 PHP Laravel的路由比较强悍,但也正因如此,不统一而容易凌乱.比如在路由中可以直接写方法操作(破坏封装啊) 以下是个人学习的例子,不供参考 路由中的直接方 ...

  5. 三十一、【WCF路由中间件】WCFHosting服务主机的路由器与负载均衡和实现思路

    回<[开源]EFW框架系列文章索引> EFW框架源代码下载V1.3:http://pan.baidu.com/s/1c0dADO0 EFW框架实例源代码下载:http://pan.baid ...

  6. 【原创】express3.4.8源码解析之路由中间件

    前言 注意:旧文章转成markdown格式. 跟大家聊一个中间件,叫做路由中间件,它并非是connect中内置的中间件,而是在express中集成进去的. 显而易见,该中间件的用途就是 ------ ...

  7. express4.x 路由中间件

    路由中间件必须通过app挂载到对应的路由上,如: var express = require('express'); var router = express.Router(); var app = ...

  8. express4.x中路由中间件和挂载路径的关系

    express4.x 中一个路由中间件可以挂载到多个路由上,一个路由也可以绑定多个路由中间件,如: //多个路由匹配一个路由中间件 app.use(['/gre+t', '/hel{2}o'], gr ...

  9. laravel之路由

    laravel之路由设置 代码如下: 访问就是: 代码附上: <?php /*|--------------------------------------------------------- ...

随机推荐

  1. centos apache安装oracle扩展

    参考网址: http://blog.csdn.net/a82168506/article/details/11763989 步骤如下: 下载安装包,下载地址.(我下载的11.1版本) http://w ...

  2. 51nod1947 栈的代价和

    1947 栈的代价和 n是5e7 只能O(n)做 大力生成函数转形式幂级数再解方程 这个是广义二项式定理: https://baike.baidu.com/item/%E4%BA%8C%E9%A1%B ...

  3. 猜数字游戏_Python

    预先设置数字变量 age_of_test = 25 #这里设置为25,也可随意 guess_age = int (input("guess age:")) if guess_age ...

  4. Linxu SSH登陆出现Access Denied错误的解决方法

    其实这个问题是从 SCP 过来的.用 SCP 在两台 Linux 服务器之间传送备份文件.输入完 root 密码后,总是出现 Permission denied, please try again.  ...

  5. 利用ajax异步校验验证码(转)

    利用ajax异步校验验证码 示例结果如图所示 具体步骤如下: step1: jsp页面及js脚本 <%@page pageEncoding="utf-8" contentTy ...

  6. [Vue CLI 3] 配置解析之 parallel

    官方文档中介绍过在 vue.config.js 文件中可以配置 parallel,作用如下: 是否为 Babel 或 TypeScript 使用 thread-loader. 该选项在系统的 CPU ...

  7. 优化SQL之最佳索引

    SQL优化工具Tosska SQL Tuning Expert for Oracle,帮助SQL开发人员解决SQL性能问题. 本工具主要创始人Richard To, 资深ITPUB元老,从1996年开 ...

  8. javascript里的eval总结

    JavaScript eval() 函数 1.定义和用法 eval() 函数计算 JavaScript 字符串,并把它作为脚本代码来执行. 如果参数是一个表达式,eval() 函数将执行表达式.如果参 ...

  9. 新一代互联网传输协议QUIC浅析

    QUIC(Quick UDP Internet Connection)是谷歌制定的一种互联网传输层协议,它基于UDP传输层协议,同时兼具TCP.TLS.HTTP/2等协议的可靠性与安全性,可以有效减少 ...

  10. windows中Navicat连接centos中的mysql报:1130-Host '192.168.xxx.1' is not allowed to connect to this MySQL解决方法

    解决方法: 在centos中登录mysql输入下面指令: grant all PRIVILEGES on *.* to ' WITH GRANT OPTION;