在 Laravel 5.3 Passport 中添加 Access-Control-Allow-Origin 标头响应

Posted

技术标签:

【中文标题】在 Laravel 5.3 Passport 中添加 Access-Control-Allow-Origin 标头响应【英文标题】:Adding Access-Control-Allow-Origin header response in Laravel 5.3 Passport 【发布时间】: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.

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

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

【问题讨论】:

这能回答你的问题吗? Laravel 5.2 CORS, GET not working with preflight OPTIONS 【参考方案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::class。 Docs【参考方案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 的第一选择 任何应用程序的第二个选项

第一个选项:

    如上例,我们创建中间件

     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, 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',的数据量

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

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

第二个选项:

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

     sudo nano /etc/nginx/sites-enabled/your-domain.conf
    

    在服务器设置服务器 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://***.com/a/70361284/2612926

【讨论】:

以上是关于在 Laravel 5.3 Passport 中添加 Access-Control-Allow-Origin 标头响应的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.3 Passport API 在 Postman 中使用个人访问令牌未经身份验证

Laravel 5.3 + Passport:总是未经身份验证的错误

在 Laravel 5.3 Passport 中添加 Access-Control-Allow-Origin 标头响应

如何使用 Laravel Passport (5.3) 记录身份验证尝试

Laravel 5.3 个人访问令牌 500

护照身份验证在 laravel 5.3 中不起作用