Lavarel HTTP中间件1

Lavarel HTTP中间件1_第1张图片
HTTP中间件

顾名思义,中间件(middleware)作为请求和响应之间的中间人,其本质是HTTP的一种过滤机制。HTTP中间件可过滤HTTP请求,由于php artisan没有中间件机制,使用middleware可为系统提供HTTP过滤层,可让系统层次更为明确。其次,由于中间可对路由进行拦截,因此可在路由的基础上增加一层保护和过滤。

HTTP中间件实现修饰模式,通过捕获请求进而处理,并将处理后的请求对象返回给下一个堆栈层。

装饰器模式即开放封闭原则下动态新增或删除功能,开放封闭原则(OCP,Open Closed Principle)即对扩展开放对修改封闭。

每当请求发送后,在执行请求前,可能需进行cookie加密、开启session、CSRF保护等操作,但每个请求各有不同,而且执行请求后可能仍需执行某些操作。因此需要根据请求的特性动态的新增操作。

应用场景

  • 授权认证
  • 加密解密
  • cookie队列
  • session读写
  • 速率限制
  • 请求解析

场景1:验证用户认证中间件
用户登录流程中,使用中间件来验证用户是否已认证,若认证失败则重定向至登录视图,若认证成功则登录请求会被认证中间件通过,并将请求传递给应用。

场景2:跨同源策略中间件
用于处理请求在被响应前添加正确的响应头

场景3:日志中间件
在应用被请求时优先记录下请求信息

[案例] 路由中使用SESSION回话
app/Http/routes.php

//未用中间件
Route::get('/', function () {
    session(['start_time'=>time()]);//存入session
    return view('welcome');
});
Route::get('/test',function(){
    return session('start_time');//获取session
});
//使用中间件
Route::group(['middleware'=>'web'],function(){
    Route::get('/', function () {
        session(['start_time'=>time()]);//存入session
        return view('welcome');
    });
    Route::get('/test',function(){
        return session('start_time');//获取session
    });
});

[疑问] 为什么 session() 放在 Route::group(['middleware'=>'web'],function(){...}) 才生效呢?
查看中间件注册文件 app/Http/Kernal.php,发现在$middlewareGrouops成员属性的web中存在SessionCookie相关的配置。

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        //关于Cookie的处理
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        //关于Session的处理
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
    ],
    'api' => [
        'throttle:60,1',
    ],
];

注册中间件

使用中间件之前必须创建并注册,Laravel中间件分为两种类型。

  • 全局中间件:在应用的每个HTTP请求中运行
  • 路由中间件:分配给特定路由使用的中间件

中间件的注册文件位于 app/Http/Kernal.php,在Kernal类中存在两个成员属性$middleware$routeMiddleware

class Kernal extends HttpKernal
{
  //注册全局中间件
  protected $middleware = [];
  //注册路由中间件
  protected $routeMiddleware = [];
}

创建中间件

可使用php artisan命令查看所有的命令选项,使用artisan命令创建中间件make:middleware,创建的中间件将保存在 app/Http/Middleware 目录下。

[验证] 中间件具有拦截HTTP请求的作用
步骤1:在CLI命令行提示界面运行命令,创建登录中间件。
使用命令行生成文件:php artisan make:middleware AdminLogin
生成中间件文件路径:app/Http/Middleware/AdminLogin.php
在中间件文件中添加配置信息

public function handler($request, Closure $next){
  echo 'stop'; //中间件具有拦截HTTP请求作用,此处应有输出。
  exit;//后续控制器中方法中断执行
  return $next($request);
}

步骤2:将AdminLogin中间件注册到路由中间件中
中间件配置文件路径:app/Http/Kernal.php

protected $routeMiddleware = [
  'admin.login'=>\App\Http\Middleware\AdminLogin::class,
];

步骤3:在路由配置文件中调用中间件
路由配置文件:app/Http/routes.php

Route::group(['middleware'=>['admin.login']], function(){
  Route::get('admin/login', 'Admin\LoginController@index');
})

步骤4:使用浏览器访问本地域名并查看页面输出
http://blog.com/admin/login

使用中间件

[案例] 用户登录时根据SESSION判断登录状态
步骤1:使用artisan命令创建后台登录中间件
php artisan make:middleware AdminLogin
步骤2:将中间件注册到路由中
app/Http/Kernal.php

protected $routeMiddleware = [
  'admin.login'=>\App\Http\Middleware\AdminLogin::class,
];

步骤3:配置路由规则
(1)设置后台登录路由
app/Http/routes.php

Route::group(['middleware'=>'web'],function(){
  //进入后台用户登录页面
  Route::get('admin/login', 'Admin\IndexController.php@login');
});

(2)处理用户登录
app\Http\Controllers\Admin\IndexController.php

public function login(){
  //用户登录成功后写入session
  session(['login_user_id'=>999]);
  return __FUNCTION__;
}

(3)设置后台首页路由
app/Http/routes.php

Route::group(['prefix'=>'admin', 'namespace'=>'Admin', 'middleware'=>['web','admin.login']], function(){
  //后台首页获取session数据
  Route('index', 'IndexController@index');//预设后台首页控制器及操作
});

(5)设置后台登录中间件
app/Http/Middleware/AdminLogin.php

public function handler($request, Closure $next){
  //若session中不存在用户登录信息则跳转至登录页面
  if(!session('login_user_id')){
    return redirect('admin/index');
  }
  //否则进入预设控制器
  return $next($request);
}

(4)预设后台首页
app/Http/Controllers/Admin/IndexController.php

public function index(){
   echo 'admin index page'; 
}

小结

  • 中间节位于路由和控制器之间
  • 中间件对HTTP请求拦截并过滤
  • 中间件自动创建 php artisan make:middleware MiddleName
  • 中间件在路由配置的关键为middleware
  • 中间件针对路由分为全局$middleware和特定routeMiddleware
  • 中间件注册和使用时应使用驼峰转小写和点号连接方式
  • 自定义中间件在 handler() 内进行编写拦截过滤业务逻辑
  • sessioncookie 需在路由分组的 middleware 参数配置 web

你可能感兴趣的:(Lavarel HTTP中间件1)