Lumen / Laravel 的跨域处理方案,自定义验证形式的实现

Lumen版本:5.3 ,更多Lumen笔记:Lumen学习笔记

首先,如果你对跨域CORS并不了解,请先阅读这篇笔记:ajax跨域处理机制,理解浏览器的跨域处理机制

下面说说 Laravel 中的跨域实现方法

  1. 完全开放跨域

    这里我直接引用别人的方案:https://gist.github.com/danharper/06d2386f0b826b669552

    • CatchAllOptionsRequestsProvider.php

      此文件作用是根据来源地址即时增加一个OPTIONS路由,并且返回成功的statusCode

        <?php namespace App\Providers;
        use Illuminate\Support\ServiceProvider;
        /**
         * If the incoming request is an OPTIONS request
         * we will register a handler for the requested route
         */
        class CatchAllOptionsRequestsProvider extends ServiceProvider {
          public function register()
          {
            $request = app('request');
            if ($request->isMethod('OPTIONS'))
            {
              app()->options($request->path(), function() { return response('', 200); });
            }
          }
        }
      

      使用方法:编辑bootstrap/app.php,插件注册代码:

        $app->register(App\Providers\CatchAllOptionsRequestsProvider::class);
      
    • CorsMiddleware.php

      此文件作用是在所有控制器前插入中间件,返回访问来源的headersorigin

        <?php namespace App\Http\Middleware;
        class CorsMiddleware {
          public function handle($request, \Closure $next)
          {
            $response = $next($request);
            $response->header('Access-Control-Allow-Methods', 'HEAD, GET, POST, PUT, PATCH, DELETE');
            $response->header('Access-Control-Allow-Headers', $request->header('Access-Control-Request-Headers'));
            $response->header('Access-Control-Allow-Origin', '*');
            return $response;
          }
        }
      

      使用方法:编辑bootstrap/app.php,把中间件加入middleware加入:

        $app->middleware([
            App\Http\Middleware\Cors::class
        ]);
      
  2. 自定义自己的拦截方案

    从以上的方案中,有两种自定义的方式,一是在CatchAllOptionsRequestsProvider.php中做限制,二是在CorsMiddleware.php中做限制。同时限制虽然也可以,但一旦两边的过滤方式不完全一样,很可能导致BUG出现,个人认为没有必要。

    以下我以修改CorsMiddleware.php为例:

     <?php
     namespace App\Http\Middleware;
     use Closure;
     use Illuminate\Auth\Access\AuthorizationException;
     class Cors
     {
         public function handle($request, Closure $next)
         {
             $response = $next($request);
             // 以下是一个例子,根据来源地址做判断,若来源地址是我站的子域名,则允许通过
             // 当然,referer是可以伪造的,所以,允许跨域始终存在风险,涉及权限的操作必须结合token验证
             $url = $request->server('HTTP_REFERER');
             if($url){
                 if(preg_match('/https?:\/\/[a-zA-Z0-9]+.gxxsite.com/i', $url, $m)){
                     $response->header('Access-Control-Allow-Origin', '*');
                 } else {
                     throw new AuthorizationException('操作违规');
                 }
             } else {
                 $response->header('Access-Control-Allow-Origin', '*');
             }
             $response->header('Access-Control-Allow-Headers', 'X-Custom-Header, Origin, Content-Type, Cookie, Accept');
             $response->header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, DELETE, OPTIONS');
             $response->header('Access-Control-Allow-Credentials', 'true');
             return $response;
         }
     }
    
若您觉得我的博文对您有帮助,欢迎点击下方按钮对我打赏
打赏