![](/img/trans.png)
[英]CRUD generated controllers and its actions are not called yii2 advanced
[英]Yii2 CORS with Auth not working for non CRUD actions
我正在 Yii2 中構建 API 並添加了 CORS 和身份驗證。 這適用於所有創建/讀取/更新/刪除操作,但不適用於自定義操作。 有沒有人經歷過這種情況?
網址管理器:
['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 在自定義操作上協同工作?
編輯:我應該補充一點,僅當瀏覽器發出OPTIONS
請求時才會出現問題 (401)。 正常請求(curl、Postman)不受影響。 問題似乎發生在 RESTful、Cors、Auth 組合中。
試試這個:
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
器,以確保cors
處理cors
。 然后我們強制cors
在實現您自己的authenticator
之前允許憑據。
另一個可能引發Unauthorized錯誤的事情是未找到或錯誤的Options
響應,因為瀏覽器首先請求它獲取允許的動詞列表。 您可以在瀏覽器的網絡選項卡中的標頭響應中檢查該列表。
一般規則是,當您要求瀏覽器對任何url執行諸如 PUT、DELETE 或 POST 之類的明智動詞時,它可能會首先向同一個url發送 OPTIONS 請求(檢查此)以在發送真實請求之前檢查該動詞是否被允許. 所以 Yii 應該被配置為通過執行正確的重定向來響應所有這些 OPTIONS 動詞。
ActiveController
實現的默認 CRUD 操作使用這些默認模式:
'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
。 它的代碼可以在這里看到。 如果你擴展了一個不同於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;
}
只需將您的 corsFilter 塊移動到驗證器塊上方,如下所示:
public function behaviors()
{
return [
'corsFilter' => [
'class' => \yii\filters\Cors::className(),
],
'authenticator' => [
'class' => HttpBearerAuth::className(),
],
'contentNegotiator' => [
'class' => ContentNegotiator::className(),
'formats' => [
'application/json' => Response::FORMAT_JSON,
],
],
];
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.