2016-03-29 2 views
4

Я создаю API в Yii2 и добавил CORS и аутентификацию. Это отлично работает для всех действий Create/Read/Update/Delete, но не для пользовательских действий. Кто-нибудь испытал это раньше?Yii2 CORS с Auth не работает для действий без CRUD

менеджер URL:

['class' => 'yii\rest\UrlRule', 'controller' => 'api/v1/user', 'pluralize' => false], 

поведения контроллера:

public function behaviors() 
{ 
    return ArrayHelper::merge([ 
      'corsFilter' => [ 
       'class' => Cors::className(), 
      ], 
      [ 
       'class' => HttpBearerAuth::className(), 
       'except' => ['options', 
          'login', 
       ], 
      ], 
     ], parent::behaviors() 
    ); 
} 

Как упоминалось выше, действия для CRUD прекрасны, но пользовательские действия, такие как http://domain.com/user/test ответит 401 Unauthorised ответ.

Невозможно ли заставить CORS и auth работать вместе над пользовательскими действиями?

Редактировать: Следует добавить, что проблема (401) возникает только тогда, когда браузер делает запрос OPTIONS. Обычные запросы (завиток, почтальон) не затрагиваются. Проблема, похоже, происходит с комбинацией RESTful, Cors, Auth.

+0

что сообщение полной ошибки упало в консоли браузера? –

+0

также какой контроллер вы используете '\ yii \ rest \ ActiveController' или' \ yii \ rest \ Controller'? вы переопределили или изменили способ работы встроенных действий 'options'? –

+0

@salem, я расширяю ActiveController. – Dubby

ответ

7

попробовать это:

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

    unset($behaviors['authenticator']); 

    $behaviors['corsFilter'] = [ 
     'class' => Cors::className(), 
     'cors' => [ 
      'Origin' => ['*'], 
      'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'], 
      'Access-Control-Request-Headers' => ['*'], 
      'Access-Control-Allow-Credentials' => true, 
     ], 
    ]; 

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

    return $behaviors; 
} 

Это незадана по умолчанию authenticator осуществляется parent controller, чтобы быть уверенным, что cors обрабатывается первым. Затем мы вынудим cors, чтобы разрешить учетные данные перед тем, как реализовать свои собственные authenticator.


Другая вещь, которая может поднять этот Несанкционированного ошибки является не обретенной или неправильно Options ответа как запрос браузера он первым, чтобы получить список разрешенных глаголов. Вы можете проверить этот список в ответе заголовков на вкладке сети вашего браузера.

Общее правило, когда вы задаете ваш браузер выполнить разумный глагол, как PUT, DELETE или POST для любого URL может первым отправить по электронной OPTIONS запрос на тот же URL (проверки this) для проверки если этот глагол разрешен перед отправкой реального запроса. Поэтому Yii должен быть настроен для ответа на все эти глаголы OPTIONS, выполнив правильные перенаправления.

действия CRUD по умолчанию, реализованные ActiveController используют те default patterns:

'PUT,PATCH {id}' => 'update', 
'DELETE {id}' => 'delete', 
'GET,HEAD {id}' => 'view', 
'POST' => 'create', 
'GET,HEAD' => 'index', 
'{id}' => 'options', 
'' => 'options', 

Так любой конфигурации ты реализовать в urlManager['rules'] обязательно не отменяет последний из них 2, и если вы используете пользовательские шаблоны всегда помнить включить его эквивалентные options глаголов, как в этом примере:

[ 
    'class' => 'yii\rest\UrlRule', 
    'controller' => ['account' => 'auth/account'], 
    'patterns' => [ 
     'POST,HEAD login' => 'login', 
     'POST,HEAD signup' => 'signup', 
     'POST req-reset-pass' => 'request-password-reset', 
     'POST reset-pass' => 'reset-password', 
     // OPTTIONS VERBS 
     'OPTIONS login' => 'options', 
     'OPTIONS signup' => 'options', 
     'OPTIONS req-reset-pass' => 'options', 
     'OPTIONS reset-pass' => 'options', 
    ] 
], 

То же самое относится и при добавлении пользовательских шаблонов в extraPatterns.


Options действие реализуется по умолчанию в ActiveController. это код можно увидеть here. В случае, если вы расширяете другой контроллер чем ActiveController как может быть \yii\rest\Controller обязательно вручную включить его:

public function actions() 
{ 
    $actions = parent::actions(); 
    $actions['options'] = [ 
     'class' => 'yii\rest\OptionsAction', 
     // optional: 
     'collectionOptions' => ['GET', 'POST', 'HEAD', 'OPTIONS'], 
     'resourceOptions' => ['GET', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'], 
    ]; 
    return $actions; 
} 
+1

ФИКСИРОВАН. Большое спасибо за тщательный ответ. Это вызвало у меня столько боли. Он добавлял объявление шаблонов в менеджер URL, который исправил его. Я всегда благодарен. – Dubby

+0

рад, что это помогло. Благодарю. –

+0

Я только что обнаружил, что когда я добавил атрибут 'patterns' в urlManager, он сломал функцию' update' (например, пользователь PUT/1). Теперь, когда я пытаюсь обновить, я получаю ответ «404». Исправлено удаление атрибута pattern. Кажется, я не могу найти решение. Есть идеи? – Dubby