Hi, sorry if I am missing something, will try to be short
Question: (correct me if I wrong)
‘yii\rest\OptionsAction’ distinguish only two cases: 1 - allowed methods for collection URL 2 - for resource URL
‘\yii\web\Controller’ has method “verbs()” and has verb filter behavior
'class' => VerbFilter::className(),
'actions' => $this->verbs(),
Shouldn’t it be expected for actions defined in verb() method, OPTIONS request to return corresponding allowed methods?
Details for my usage:
My url menager config
'urlManager' => [
'class' => 'yii\web\UrlManager',
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => 'v1/user',
'tokens' => [
'{id}' => '<id:\\d[\\d,]*>',
],
'patterns' => [
// common actions
'GET,HEAD' => 'index',
'POST' => 'create',
'POST login' => 'login',
// actions to themselves (user is get by Bear authorization token)
'GET dashboard' => 'dashboard',
'PUT' => 'update',
// actions by id
'GET,HEAD {id}' => 'view',
'OPTIONS login' => 'options',
'users' => 'options',
'{id}' => 'options',
'' => 'options',
]
],
My current user controller
class UserController extends ActiveController {...
public function behaviors() {
$behaviors = parent::behaviors();
$behaviors[1] = [
'class' => Cors::className(),
'cors' => [
// restrict access to
'Origin' =>[ Yii::$app->params['client_url']],
'Access-Control-Request-Method' => [ 'GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS' ],
'Access-Control-Request-Headers' => [ '*' ],
'Access-Control-Allow-Origin ' => Yii::$app->params['client_url'],
'Access-Control-Max-Age' => 86400,
'Access-Control-Expose-Headers' => [ ]
]
];
$behaviors['authenticator'] = [
'class' => HttpBearerAuth::className(),
'except' => [ 'login','options'],
];
// not sure if it needed here
$behaviors['access'] = [
'class' => AccessControl::className(),
'rules' => [
['allow' => true, 'actions' => ['options']],
],
];
return $behaviors;
}
protected function verbs()
{
return [
'index' => ['GET', 'HEAD'],
'view' => ['GET', 'HEAD'],
'create' => ['POST'],
'update' => ['PUT', 'PATCH'],
//'delete' => ['DELETE'],
'login' => ['POST'],
];
}
/* My implementation for Options check */
public function actionOptions() {
if (Yii::$app->getRequest()->getMethod() !== 'OPTIONS') {
Yii::$app->getResponse()->setStatusCode(405);
}
$action_raw = Yii::$app->getRequest()->getUrl();
$path = explode('/',parse_url($action_raw)['path']);
$action = end($path);
$options = $this->verbs();
if(isset($options[$action])) {
Yii::$app->getResponse()->getHeaders()->set('Allow', implode(', ', $options[$action]));
} elseif(isset($options['*'])) {
Yii::$app->getResponse()->getHeaders()->set('Allow', implode(', ', $options['*']));
} else {
Yii::$app->getResponse()->setStatusCode(405);
}
}
One more question, is it required to explicitly define rule pattern like this one
‘OPTIONS login’ => ‘options’,
without it I’m receiving 404 page not found response.
thanks, best regards
Arsen