web-dev-qa-db-ja.com

Laravel 5.2 CORS、プリフライトオプションでGETが機能しない

恐ろしいCORSエラー:

Cross-Origin Request Blocked:Same Origin Policyは、 http:// localhost/mysite/api/test でリモートリソースの読み取りを許可しません。 (理由:CORSヘッダー 'Access-Control-Allow-Origin'がありません)。

Laravelルート:

$router->group(['prefix' => 'api', 'middleware' => 'cors'], function ($router) {
    $router->get('/test', 'MyController@myMethod');
});

Laravel Cors Middlware:

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::make('OK', 200, $headers);
        }

        $response = $next($request);
        foreach ($headers as $key => $value)
            $response->header($key, $value);
        return $response;
    }

Laravelカーネル:

 protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'cors' => \App\Http\Middleware\CORS::class
    ];

関連する.htaccess:

RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

関連するVue.js:

 new Vue({
        el: '#app',
        data: {
           //data here
        },
        http: {
            headers: {
                "Authorization": "Basic " + "apiKeyHere"
            }
        },
        methods: {
            mymethod: function (e)
            {
                e.preventDefault();
                this.$http.get('http://localhost/mysite/api/test').then(
                        function (response)
                        {
                          //do something
                        }
                )
            }
        }
    });

Authorizationヘッダーオプションを取り出すと、リクエストは機能します。

https://github.com/barryvdh/laravel-cors も試しましたが、まだ喜びはありません。どんな助けも感謝します!

22
suncoastkid

明らかに理想的なソリューションではありませんが、機能します。これをroutes.phpファイルの先頭に追加しました。

header('Access-Control-Allow-Origin: *');
header( 'Access-Control-Allow-Headers: Authorization, Content-Type' );

ハッキングせずにこれを機能させるのはいいことです...

更新:IIS関連。

<httpProtocol>
    <customHeaders>
       <add name="Access-Control-Allow-Headers" value="Origin, Authorization, X-Requested-With, Content-Type, Accept" />
       <add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS,PUT,DELETE" />
    </customHeaders>
</httpProtocol>

アクセスを制限する場合は、アウトバウンドルールを追加できます。

      <outboundRules>
          <clear />
                <rule name="AddCrossDomainHeader">
                    <match serverVariable="RESPONSE_Access_Control_Allow_Origin" pattern=".*" />
                    <conditions logicalGrouping="MatchAll" trackAllCaptures="true">
                        <add input="{HTTP_Origin}" pattern="(http(s)?://((.+\.)?somesite\.com|(.+\.)?anothersite\.org))" />
                    </conditions>
                    <action type="Rewrite" value="{C:0}" />
                </rule>
      </outboundRules>
24
suncoastkid

Routes.phpにこれらの行を追加するだけで問題を解決しますLaravel 5.2 routes/web.phpの5.2より大きい場合

header('Access-Control-Allow-Origin:  *');
header('Access-Control-Allow-Methods:  POST, GET, OPTIONS, PUT, DELETE');
header('Access-Control-Allow-Headers:  Content-Type, X-Auth-Token, Origin, Authorization');

またはCorsミドルウェアをグローバルHTTPミドルウェアスタックに登録する

protected $middleware = [
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
    \App\Http\Middleware\CorsMiddleware::class
];
15
M Arfan

ミドルウェアは問題ありませんが、CorsミドルウェアをグローバルHTTPミドルウェアスタックに登録する必要があります。

protected $middleware = [
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
    \App\Http\Middleware\CorsMiddleware::class
];
6
Utwo

実際、問題はプリフライトリクエストから発生しますが、処理方法には、Laravel-主にOPTIONSリクエストがルーティングされる(何か他の答えはPHP= way、than Laravel way)ではなく、それを成功させるためにあなたのルートにこれを追加する必要があります:

Route::options('/{any}', function(){ return ''; })->where('any', '.*');

それでは、他のすべての方法に対応しましょう-CORSミドルウェアを作成します。

_namespace App\Http\Middleware;

use Closure;

class Cors
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request)
            ->header('Access-Control-Allow-Origin', '*')
            ->header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, DELETE');
    }
}
_

そして最後に、与えられたルートに対して、そのミドルウェアを使用します。

Route::put('/test', function(){ echo('test'); })->with('cors');

5
eithed

Barryvdh\Corsのようなミドルウェアを使用せずにLaravelを使用して、これをバイパスできます。index.phpにLaravelカーネルのインスタンス化の直前

header('Access-Control-Allow-Origin: http://localhost:8001');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token,Authorization');
header('Access-Control-Allow-Credentials: true');

前にこれを追加します

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

これは、JWT AUTHでも適切に機能するはずです。 Access-Control-Allow-HeadersにはAuthorizationを含める必要があります。そうしないと、accesstokenはAuthorizationヘッダーで許可されないため、JWT AUTHは失敗します。ハッピーコーディング。

3
SOUMYA

私の解決策:

$router->group(['prefix' => 'api', 'middleware' => 'cors'], function ($router){
    $router->options('{param1?}/{param2?}/{param3?}', function () {});
});
0
Gierappa