简介#

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. 直接在安装了redis的Linux机器上操作redis数据存储类型--List类型

    一.概述: 在Redis中,List类型是按照插入顺序排序的字符串链表.和数据结构中的普通链表一样,我们可以在其头部(left)和尾部(right)添加新的元素.在插入时,如果该键并不存在,Redis ...

  2. jnhs解决办法部署错误: 未能启动 Tomcat, 服务器端口 8084 已在使用中。

    当然重启电脑是不可能重启电脑的,这辈子都不会重启电脑 解决方法 1. win + R,输入cmd回车进打开命令行工具 2. 输入 netstat -ano|findstr 8084 查看占用8080端 ...

  3. springmvc下载一个文档下载接口里的文档

    A提供了一个文件下载的接口,在调用的时候可以直接在前端用a标签来调用 <a href="http://" target="_blank">下载< ...

  4. day38 01-Spring框架的概

    Action里面调Service,Service里面调DAO,在Action里面new一个Service,在Service里面new一个DAO.有了Spring之后可以不用new对象了.AOP里面有很 ...

  5. 洛谷P1002 过河卒 [2017年4月计划 动态规划15]

    P1002 过河卒 题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之 ...

  6. leetcode 235-290 easy

    235. Lowest Common Ancestor of a Binary Search Tree 公共的祖先必定大于左点小于右点,否则不断递归到合适. class Solution { publ ...

  7. Hdu 2389 二分匹配

    题目链接 Rain on your Parade Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 655350/165535 K (Ja ...

  8. Hdu 1299

    Diophantus of Alexandria Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  9. MR25H10-1Mb密度SPI串行接口MRAM

    everspin的MR25H10是一个1,048,576位磁阻随机存取存储器(MRAM)设备,由131,072个8位字组成.MR25H10提供串行EEPROM和串行闪存兼容的读/写时序,没有写延迟,并 ...

  10. 手机端点击键盘无法获取keyCode值的部分时隐藏键盘并执行事件

    用计时器监视window.innerHeight高度改变来判断.触发键盘其他地方也有事件反应 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 ...