@Inogami
php-программист, поковыриваю vue

Как настроить cors в yii2?

Делаю фронтэнд на vue, есть бэкэнд на yii2, при запросе через fetch на бэкенд yii не пропускает options
Выдаёт:
Access to fetch at 'http://smarthouse/api/121/rooms' from origin 'http://vue.home' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

В логах следующее:
smarthouse: 127.0.0.1 [26/Jan/2019:11:50:31 +0700] "OPTIONS /api/121/rooms HTTP/1.1" 404 27041 "http://vue.home/rooms/121" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"

Контроллеры на бэке наследую от RestController который наследую от yii\rest\ActiveController
Код RestController:
spoiler
<?php

namespace app\controllers;

use yii\rest\ActiveController;
use yii\filters\auth\HttpBearerAuth;
use yii\filters\AccessControl;
class RestController extends ActiveController
{
    public $enableCsrfValidation = false;

    public function actions()
    {
        return [
            'options' => [
                'class' => 'yii\rest\OptionsAction',
            ],
        ];
    }

    public function behaviors()
    {
        $behaviors = parent::behaviors();

        $behaviors['corsFilter'] = [
            'class' => \yii\filters\Cors::class,
            'cors' => [
                // restrict access to
                'Origin' => ['http://vue.home'],
                // Allow only POST and PUT methods
                'Access-Control-Request-Methods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
                // Allow only headers 'X-Wsse'
                'Access-Control-Request-Headers' => ['Content-Type', 'Authorization'],
                // Allow credentials (cookies, authorization headers, etc.) to be exposed to the browser
                'Access-Control-Allow-Credentials' => true,
                // Allow OPTIONS caching
                'Access-Control-Max-Age' => 3600,
                // Allow the X-Pagination-Current-Page header to be exposed to the browser.
                'Access-Control-Expose-Headers' => ['X-Pagination-Current-Page'],
            ],
        ];

        unset($behaviors['authenticator']);
        $behaviors['authenticator'] = [
            'class' =>  HttpBearerAuth::class,
            'except' => ['options'],
        ];
        $behaviors['authenticator']['except'] = ['login'];

        $behaviors['access'] = [
            'class' => AccessControl::class,
            'rules' => [
                [
                    'allow' => true,
                    'roles' => ['@'],
                ],
                [
                    'allow' => true,
                    'actions' => ['login'],
                    'roles' => ['?']
                ]
            ],
        ];

        return $behaviors;
    }
}


в web.php:
spoiler
'parsers' => [
                'application/json' => 'yii\web\JsonParser',
            ]
...
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
                '/api/login' => 'user/login',
                [
                    'class' => 'yii\rest\UrlRule',
                    'controller' => ['user'],
                ],
                [
                    'class' => 'yii\rest\UrlRule',
                    'controller' => ['room'],
                    'prefix' => 'api/',
                    'extraPatterns' => [
                        '<id>/devices' => 'devices'
                    ]
                ],
                [
                    'class' => 'yii\rest\UrlRule',
                    'controller' => ['device'],
                    'prefix' => 'api/',
                ],
                [
                    'class' => 'yii\rest\UrlRule',
                    'controller' => ['macro'],
                    'prefix' => 'api/',
                ]
            ],
        ],

В .htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php
  • Вопрос задан
  • 6288 просмотров
Пригласить эксперта
Ответы на вопрос 3
Вам необходимо с бэкэнда отвечать на предполётный CORS-запрос, а вы этого не делаете, из-за чего и возникает ошибка. Почитайте эту статью про CORS
Ответ написан
Комментировать
xakplant
@xakplant
Автор сайта xakplant.ru
Вы можете прочитать статью "Fetch и CORS. Пример на ReactJS и другие"

Кажется вам нужно в ответе на запрос отдать заголовки:
Access-Control-Allow-Credentials: true
// Тут перечисляем наши заголовки
Access-Control-Allow-Headers: Authorization, прочие заголовки запроса... 
// Перечисляем разрешённые методы
Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS
// Пишем домен с которого отправляем запрос
Access-Control-Allow-Origin: https://yourdomain.ru
Ответ написан
Комментировать
@VikingBO
Для выяснения более подробно причин возврата ответа yii2 отправляет информацию о debug, ссылка на эту инфу отправляется в заголовке:
5e904ffaba55e007746249.png

вы можете эту ссылку посмотреть на домене куда делаете запрос и там будет подробно описано на каком этапе и по какой причине вернулась ошибка.
Судя по логу он просто возвращает 404 ошибку на запрос, то есть очень похоже что проблема не в CORS, а уже в роутинге.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы