【问题标题】:Adding Access-Control-Allow-Origin header response in Laravel 5.3 Passport在 Laravel 5.3 Passport 中添加 Access-Control-Allow-Origin 标头响应
【发布时间】:2017-01-18 15:51:04
【问题描述】:

我是 Laravel 新手,正在做一些 Laravel 5.3 Passport 项目,并授予 OAuth2.0 密码。当我使用参数卷曲 API 时,它会以令牌响应。但是,在浏览器中,它需要端点应该添加的额外安全性,因为我的请求来自本地主机,而 API 位于我的 VM 中。这是错误:

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. The response had HTTP status code 400.

我知道问题出在哪里,但我不知道在哪里包含该标题,因为这是第三方应用程序。

先谢谢各位专家了。请帮忙。

【问题讨论】:

标签: cors laravel-5.3


【解决方案1】:

简单的答案是将Access-Control-Allow-Origin 标头设置为localhost*。这是我通常的做法:

创建一个名为Cors的简单中间件:

php artisan make:middleware Cors

将以下代码添加到app/Http/Middleware/Cors.php

public function handle($request, Closure $next)
{
    return $next($request)
        ->header('Access-Control-Allow-Origin', '*')
        ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
}

您可以将* 替换为localhost 或保持原样。

下一步是加载中间件。将以下行添加到app/Http/Kernel.php 中的$routeMiddleware 数组中。

'cors' => \App\Http\Middleware\Cors::class, 

最后一步是在要设置访问源标头的路由上使用中间件。假设你说的是 laravel 5.3 中新的 api 路由,做的地方是 app/Providers/RouteServiceProvider.php,在 mapApiRoutes() 函数里面(你可以删除或注释函数之前的代码):

    Route::group([
        'middleware' => ['api', 'cors'],
        'namespace' => $this->namespace,
        'prefix' => 'api',
    ], function ($router) {
         //Add you routes here, for example:
         Route::apiResource('/posts','PostController');
    });

【讨论】:

  • 我也在尝试使这项工作 (see here) 但由于某种原因只有 GET 请求有效。知道为什么 POST 不适用于我的设置吗?另外.. 中间件的顺序似乎很重要。
  • 我正在进行 ajax 调用,这个解决方案对我不起作用,有什么建议吗?
  • 对我的 Laravel 5.6 和 Angular 5 应用程序来说非常清楚。谢谢!
  • 代替最后一步,只需在路由的末尾添加:Route::get('/url','controller@function') -> middleware('cors');跨度>
  • Laravel 8 已经包含了 cors 中间件。但也不适用于我(不需要身份验证,因为没有用户存储在数据库中)
【解决方案2】:

简单的答案是将 Access-Control-Allow-Origin 标头设置为 localhost 或 *。这是我通常的做法:

将以下代码添加到 bootstrap/app.php:

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: *');
header('Access-Control-Allow-Headers: *');

警告:仅在您的开发人员环境中执行此操作。

【讨论】:

  • 我认为它会更像这样:header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: *'); header('Access-Control-Allow-Headers: Origin, X-Requested-With,Authorization, Content-Type, Accept');
  • 这是否会使您的应用程序容易受到攻击,因为您还允许所有人发布到您的整个应用程序?
  • 永远不要这样做,这意味着任何人都可以将数据发布到您的应用程序。
  • 仅供开发使用,谢谢
  • 终于有一些适用于 Laravel 8 的东西了..
【解决方案3】:

您也可以使用很棒的laravel-cors package by barryvdh

安装包后,为所有路由获取 CORS 支持的最简单方法是在 Http/Kernel.php 中添加这样的中间件:

protected $middleware = [
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
    \Barryvdh\Cors\HandleCors::class,
];

如果您不想在所有路由上都支持 CORS,您应该为 /oauth/token 创建一个新的 OPTIONS 路由,并将 cors 中间件仅添加到该路由。

为 Laravel 8 编辑

Laravel 8 已经内置了 CORS 支持 - HandleCors 中间件在您的全局 middleware stack by default 中定义,并且可以在您的应用程序的 config/cors.php 配置文件中进行配置。

如果您更新 Laravel 应用程序,请务必使用提供的中间件更改 barryvdh 的包:\Fruitcake\Cors\HandleCors::class

【讨论】:

  • 现在应该是\Fruitcake\Cors\HandleCors::class,而不是\Barryvdh\Cors\HandleCors::classDocs
【解决方案4】:

App\Http\Kernel设置路由中间件没有解决问题的,尝试设置全局中间件。在App\Http\Middleware\Cors:

public function handle($request, Closure $next)
{
    return $next($request)->header('Access-Control-Allow-Origin', '*')
        ->header('Access-Control-Allow-Methods','GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS')
        ->header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
}

App\Http\Kernel:

protected $middleware = [
    ...
    \App\Http\Middleware\Cors::class,
];

【讨论】:

  • 这成功了!!!早些时候有 Cors 中间件作为路由中间件,它无助于解决 OPTIONS 方法请求(预检)。将 Cors 设置为全局中间件处理所有传入请求,包括 Preflight 请求。添加到答案中,如果 allow-credentials 为真,则将 allow-origin 设置为 * 将不起作用。如果 Allow-Credentials 为 true,则必须具体说明来源。可以从请求头中获取源,然后添加到响应头中。
【解决方案5】:

在 App/Http/Middleware 中创建一个 Cors.php 文件并将其粘贴到其中。 ☑

<?php

namespace App\Http\Middleware;

use Closure;


class Cors {    public function handle($request, Closure $next)
    {
        header("Access-Control-Allow-Origin: *");
        //ALLOW OPTIONS METHOD
        $headers = [
            'Access-Control-Allow-Methods' => 'POST,GET,OPTIONS,PUT,DELETE',
            'Access-Control-Allow-Headers' => 'Content-Type, X-Auth-Token, Origin, Authorization',
        ];
        if ($request->getMethod() == "OPTIONS"){
            //The client-side application can set only headers allowed in Access-Control-Allow-Headers
            return response()->json('OK',200,$headers);
        }
        $response = $next($request);
        foreach ($headers as $key => $value) {
            $response->header($key, $value);
        }
        return $response;

    } }

并将这一行添加到您的 Kernel.php 中的“Trust Proxies::Class”行之后。

\App\Http\Middleware\Cors::class,

就是这样,您已允许所有 Cors 标头。 ☑

【讨论】:

    【解决方案6】:

    之后 https://github.com/fruitcake/laravel-cors 我必须在 cors.php 文件中进行如下更改

         * Sets the Access-Control-Allow-Credentials header.
         */
        'supports_credentials' => true,
    

    【讨论】:

    • 在 laravel 的 config/cors.php 文件中设置上述键值 'supports_credentials' => true 后,清除配置缓存(php artisan config:clear),路由缓存(php artisan route:clear)和普通缓存(php artisan cache:clear)。它适用于 cors.php 文件中定义的路径。
    【解决方案7】:

    小心,您不能修改预检。 另外,浏览器(至少chrome)去掉了“授权”标头……这导致了一些根据路由设计可能会出现的问题。例如,预检将永远不会进入护照路线表,因为它没有带有令牌的标题。

    如果你正在设计一个实现了 options 方法的文件,你必须在路由文件 web.php 中定义一个(或多个)“trap”路由,以便 preflght(没有头授权)可以解析请求并获取对应的CORS头。 因为他们默认不能在中间件 200 中返回,所以必须在原始请求上添加 headers。

    【讨论】:

      【解决方案8】:

      如果您已经应用了 CORS 中间件,但仍然无法正常工作,请尝试此操作。

      如果您的 API 的路由是:

      Route::post("foo", "MyController"})->middleware("cors");
      

      然后你需要改变它以允许 OPTIONS 方法:

      Route::match(['post', 'options'], "foo", "MyController")->middleware("cors");
      

      【讨论】:

        【解决方案9】:

        如果由于某种原因它仍然无法正常工作。 Laravel 的第一选择 任何应用程序的第二个选项

        第一个选项:

        1. 如上例,我们创建中间件

           php artisan make:middleware Cors
          
        2. 将以下代码添加到app/Http/Middleware/Cors.php

           public function handle($request, Closure $next) 
           {
               return $next($request)
                   ->header('Access-Control-Allow-Origin', '*')
                   ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS')
                   ->header('Access-Control-Allow-Headers', 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'); 
           }
          

        仔细看,表头-&gt;header('Access-Control-Allow-Headers',的数据量

        1. 第三步,在app/Http/Kernel.php中的$routeMiddleware数组中添加中间件

           protected $routeMiddleware = [
               ....
               'cors' => \App\Http\Middleware\Cors::class,
           ];
          

        第二个选项:

        1. 为您的域打开 nginx.conf 设置。

           sudo nano /etc/nginx/sites-enabled/your-domain.conf
          
        2. 在服务器设置服务器{ listen 80; .... }里面请添加以下代码:

           add_header 'Access-Control-Allow-Origin' '*';
           add_header 'Access-Control-Allow-Credentials' 'true';
           add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
           add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH';
          

        【讨论】:

        • 第一个选项是我的解决方案,让资产恢复启用 cors
        【解决方案10】:

        只需将其添加到您的代码控制器中

        return response()->json(compact('token'))->header("Access-Control-Allow-Origin",  "*");
        

        【讨论】:

        • 请将您的答案始终放在内容中,而不是简单地粘贴代码,谢谢!
        • 你能解释一下为什么吗?
        【解决方案11】:

        Access-Control-Allow-Origin 标头添加到localhost or *. 的几个步骤

        第 1 步:创建 Cors 中间件:

        php artisan make:middleware Cors
        

        第 2 步:像这样在 Cors 中间件中设置标头

        public function handle($request, Closure $next)
            {
                $response = $next($request);
                $response->headers->set('Access-Control-Allow-Origin' , '*');
                $response->headers->set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE');
                $response->headers->set('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, X-Requested-With, Application');
        
                return $response;
            }
        

        第 3 步:我们需要在 app/Http/Kernel.php 中添加 Cors 类

         protected $middleware = [
                ....
                \App\Http\Middleware\Cors::class,
            ];
        

        这里不需要检查任何中间件 因为我们在 $middleware 中添加 Cors 类在 app/Http/Kernel.php

        【讨论】:

          【解决方案12】:

          工作解决方案

          第 1 步:创建 Cors 中间件

          php artisan make:middleware Cors
          

          第 2 步:在句柄函数内的 Cors 中间件中设置标头

          return $next($request)
                  ->header('Access-Control-Allow-Origin', '*')
                  ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
          

          第 3 步:在 app/Http/Kernel.php

          中添加 Cors 类
          protected $routeMiddleware = [
              ....
              'cors' => \App\Http\Middleware\Cors::class,
          ];
          

          第四步:替换app/providers/routeServiceProvider.php中的mapApiRoutes

          Route::prefix('api')
                   ->middleware(['api', 'cors'])
                   ->namespace($this->namespace)
                   ->group(base_path('routes/api.php'));
          

          第 5 步:在 routes/api.php

          中添加您的路线
          Route::post('example', 'controllerName@functionName')->name('example');
          

          【讨论】:

            【解决方案13】:

            只需将此添加到您的视图中:

            <?php header("Access-Control-Allow-Origin: *"); ?>
            

            【讨论】:

            • 查看?为什么?这是 Restful API
            【解决方案14】:

            我正在使用 Laravel 8 并且刚刚安装了 fruitcake/laravel-cors 并在 app/Http/Kernel.php 中使用它,就像一击:

            protected $middleware = [
                  ....
                     \Fruitcake\Cors\HandleCors::class,
                ];
            

            注意: 像我一样将它添加到数组的末尾

            【讨论】:

              【解决方案15】:

              您可以通过在 bootstrap/app.php 中添加标头轻松完成此操作

              header('Access-Control-Allow-Origin: *');
              header('Access-Control-Allow-Methods: *');
              header('Access-Control-Allow-Headers: *');
              

              【讨论】:

                【解决方案16】:

                你不需要做任何额外的事情。 Laravel 已经内置了 - 从这里阅读 https://stackoverflow.com/a/70361284/2612926

                【讨论】:

                  猜你喜欢
                  • 2021-12-16
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-09-21
                  • 1970-01-01
                  • 2011-06-27
                  • 2016-07-03
                  • 2017-09-19
                  相关资源
                  最近更新 更多