R
R
Rustam Akimov2019-01-26 08:02:37
Yii
Rustam Akimov, 2019-01-26 08:02:37

How to setup cors in yii2?

I make a frontend on vue, there is a backend on yii2, when requesting via fetch on the yii backend, it does not skip options . It gives out
:

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.

The following is in the logs:
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"

Controllers on the back inherit from RestController which inherits from yii\rest\ActiveController
RestController code:
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;
    }
}

in 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/',
                ]
            ],
        ],

In .htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
Alexander, 2019-01-26
@zkelo

You need to respond to the pre-flight CORS request from the backend, but you don't, which is why the error occurs. Read this article about CORS

B
Boris Cherepanov, 2019-06-22
@xakplant

You can read the article " Fetch and CORS. An example on ReactJS and others "
It seems that you need to give headers in the response to the request:

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

V
VikingBO, 2020-04-10
@VikingBO

To find out in more detail the reasons for returning a response, yii2 sends information about debug, a link to this information is sent in the header:
5e904ffaba55e007746249.png
you can look at this link on the domain where you are making the request and it will describe in detail at what stage and for what reason the error returned.
Judging by the log, it simply returns a 404 error on the request, that is, it is very likely that the problem is not in CORS, but already in the routing.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question