Следуя этому вопросу, я установил поведение контроллера останова как
public function behaviors() { $behaviors = parent::behaviors(); $auth= $behaviors['authenticator'] = [ 'class' => HttpBearerAuth::className(), 'only' => ['dashboard'], ]; $behaviors['contentNegotiator'] = [ 'class' => ContentNegotiator::className(), 'formats' => [ 'application/json' => Response::FORMAT_JSON, ], ]; $acces=$behaviors['access'] = [ 'class' => AccessControl::className(), 'only' => ['login'], 'rules' => [ [ 'actions' => ['login'], 'allow' => true, 'roles' => ['?'], ], ], ]; unset($behaviors['authenticator']); unset($behaviors['access']);
И теперь фильтры корса
// add CORS filter $behaviors['corsFilter'] = [ 'class' => \yii\filters\Cors::className(), 'cors' => [ // restrict access to 'Access-Control-Allow-Origin' => ['*'], 'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'], // Allow only POST and PUT methods 'Access-Control-Request-Headers' => ['*'], // Allow only headers 'X-Wsse' 'Access-Control-Allow-Credentials' => true, // Allow OPTIONS caching 'Access-Control-Max-Age' => 86400, // Allow the X-Pagination-Current-Page header to be exposed to the browser. 'Access-Control-Expose-Headers' => [], ] ]; // re-add authentication filter $behaviors['authenticator'] = $auth; $behaviors['access'] = $access; // avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method) $behaviors['authenticator']['except'] = ['options']; return $behaviors; }
Мой фронтмен angular2 как
const body = JSON.stringify(user); let headers = new Headers(); headers.append('Content-Type', 'application/x-www-form-urlencoded'); headers.append('Content-Type', 'application/json'); headers.append('Access-Control-Allow-Credentials', "*"); return this._http.post(this.loginUrl, body, { headers:headers }) .map((response: Response) => { //process response }) .catch(this.handleError);
Но я все еще получаю ошибку
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
Что может быть неправильным, так как ive установил фильтр cors в yii2 поведении отключил аутентификатор и добавил его позже. Что я могу упустить?
Я также проверил эту ссылку, а также эту, но никто не решает проблему
В случае возникновения проблем с заголовками CORS, я рекомендую использовать следующую инструкцию:
Добавьте конфигурацию cors к вашему контроллеру. Например:
/** * List of allowed domains. * Note: Restriction works only for AJAX (using CORS, is not secure). * * @return array List of domains, that can access to this API */ public static function allowedDomains() { return [ // '*', // star allows all domains 'http://test1.example.com', 'http://test2.example.com', ]; } /** * @inheritdoc */ public function behaviors() { return array_merge(parent::behaviors(), [ // For cross-domain AJAX request 'corsFilter' => [ 'class' => \yii\filters\Cors::className(), 'cors' => [ // restrict access to domains: 'Origin' => static::allowedDomains(), 'Access-Control-Request-Method' => ['POST'], 'Access-Control-Allow-Credentials' => true, 'Access-Control-Max-Age' => 3600, // Cache (seconds) ], ], ]); }
Вышеприведенный код добавит в ответ специальные http-заголовки. Проверьте http-заголовки с помощью инструментов отладки браузера:
Запрос http-заголовка должен содержать Origin
. Он будет автоматически добавлен браузером в Crossdomain AJAX. Этот http-заголовок может быть добавлен также через вашу JS-библиотеку. Без этого http-заголовка corsFilter
не будет работать.
POST /api/some-method-name HTTP/1.1 Host: api.example.com Connection: keep-alive Content-Length: 86 Accept: */* Origin: https://my-site.example.com User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Referer: https://my-site.example.com/ Accept-Encoding: gzip, deflate, br Accept-Language: en-GB,en;q=0.8,en-US;q=0.6,ru;q=0.4
В заголовках ответов http должны быть Access-Control-*
заголовки Access-Control-*
. Этот http-заголовок будет добавлен corsFilter
.
HTTP/1.1 200 OK Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: https://my-site.example.com Content-Type: application/json; charset=UTF-8 Date: Fri, 24 Feb 2017 09:21:47 GMT Server: Apache Content-Length: 27 Connection: keep-alive
Если вы не видите эти HTTP-заголовки в ответ , возможно, это означает, что \yii\filters\Cors
не работает.
Проверьте другие типы поведения / фильтры в контроллере. Попробуйте добавить corsFilter
качестве первого поведения . Вероятно, некоторые другие действия предотвращают выполнение corsFilter
.
Попробуйте отключить проверку CSRF для этого контроллера (это может помешать внешнему доступу):
/** * Controller for API methods. */ class ApiController extends Controller { /** * @var bool See details {@link \yii\web\Controller::$enableCsrfValidation}. */ public $enableCsrfValidation = false; // ... }
Кроме того, необходимо проверить ваш веб-сервер. Вероятно, nginx может потребовать дополнительной настройки, apache может потребовать перезагрузки .
Access-Control-*
заголовки в ответе могут быть добавлены с помощью веб-сервера (см. Apache и nginx ). Но я не рекомендую использовать этот способ, потому что в этом случае вы не можете управлять http-айерами с помощью приложения.
Некоторые полезные сведения можно найти здесь:
Попробуй это :
public static function allowedDomains() { return [ // '*', // star allows all domains 'http://localhost:3000', 'http://test2.example.com', ]; } public function behaviors() { return array_merge(parent::behaviors(), [ // For cross-domain AJAX request 'corsFilter' => [ 'class' => \yii\filters\Cors::className(), 'cors' => [ // restrict access to domains: 'Origin' => static::allowedDomains(), 'Access-Control-Request-Method' => ['POST'], 'Access-Control-Allow-Credentials' => true, 'Access-Control-Max-Age' => 3600, // Cache (seconds) ], ], ]); }
Добавьте эту функцию на свой контроллер.
И One Thing angular2 используют метод OPTION в первый раз. Для этого также разрешите метод OPTION