Php Yii2 Rest-自定义操作和选项方法
我的UsersController类中的以下操作“/login”路由操作有问题Php Yii2 Rest-自定义操作和选项方法,php,rest,yii2,Php,Rest,Yii2,我的UsersController类中的以下操作“/login”路由操作有问题 public function actionLogin(){ $data = Yii::$app->getRequest()->getBodyParams(); $model = new Usuario(); //Validamos que se hayan recibido los campos if(empty($data['email
public function actionLogin(){
$data = Yii::$app->getRequest()->getBodyParams();
$model = new Usuario();
//Validamos que se hayan recibido los campos
if(empty($data['email']) || empty($data['password'])){
throw new \yii\web\BadRequestHttpException("Debe ingresar email y password");
}
//Validamos usuario y contraseña
$usuario = $model->findByUsername($data['email']);
if(empty($usuario) || !$usuario->validatePassword($data['password'])){
throw new \yii\web\UnauthorizedHttpException("Usuario y/o contraseña incorrectos");
}
return $usuario;
}
情况是,我正在使用POST方法执行登录,并且我正在从不同的域调用此路由,因此前端库首先尝试使用OPTIONS方法调用/登录路由,以检查是否允许使用POST调用/登录
问题在于yii2 rest-ActiveController的内置功能仅适用于/users和/users/{id}
如果我通过actions verbFilter手动添加此/登录路径,使其在POST和OPTIONS中都可用,那么yii实际上是在尝试使用OPTIONS请求调用登录操作。我的意思是,它正在尝试执行登录。当然不能,因为它没有发送电子邮件和密码字段,但我可以在日志文件中看到一个错误
所以,我的问题是。。。是否有任何方法可以正确配置此“自定义”路由操作并使选项透明地执行?因为我希望在使用OPTIONS调用登录操作时不会执行它,而是直接返回OPTIONS-allowed-methods头
更新信息:添加了URL管理器规则
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => true,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/users'],
'pluralize' => false,
'tokens' => [
'{id}' => '<id:\\w+>'
]
],
//Rutas usuario
'v1/login' => '/v1/users/login'
],
],
'urlManager'=>[
“enablePrettyUrl”=>true,
'enableStrictParsing'=>true,
'showScriptName'=>true,
“规则”=>[
[
'class'=>'yii\rest\UrlRule',
“控制器”=>[“v1/用户”],
“多元化”=>错误,
“代币”=>[
“{id}”=>”
]
],
//乌萨里奥酒店
“v1/login'=>”/v1/users/login”
],
],
您需要在控制器的行为()
方法(请参见如何)中附加Cors
过滤器,条件如下:
Cors
过滤器应在身份验证/授权过滤器之前定义AccessControl
过滤器中的操作选项的访问权限
UsersController
可能有这样的行为()
方法:
public function behaviors()
{
return ArrayHelper::merge(
[
'cors' => [
'class' => Cors::className(),
],
],
parent::behaviors(),
[
'access' => [
'class' => AccessControl::className(),
'rules' => [
['allow' => true, 'actions' => ['options']],
]
],
]
);
}
默认情况下,
yii\rest\UrlRule
类将这些模式应用于任何端点:
'patterns' => [
'PUT,PATCH {id}' => 'update',
'DELETE {id}' => 'delete',
'GET,HEAD {id}' => 'view',
'POST' => 'create',
'GET,HEAD' => 'index',
'{id}' => 'options',
'' => 'options',
]
这意味着,如果您的登录操作
是在扩展了ActiveController的类中编写的,则任何包含选项谓词的请求都将重定向到yii\rest\optionAction
我建议将模式
替换为只使用动词,因为您的登录操作不需要任何其他CRUD操作。这应该适用于您的案例:
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/users'],
'pluralize' => false,
'tokens' => [
'{id}' => '<id:\\w+>'
]
],
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/login' => '/v1/users/login'],
'patterns' => [
'POST' => 'login',
'' => 'options',
]
]
],
我通过扩展Cors过滤器类解决了这个问题:
use Yii;
use yii\filters\Cors;
class CorsCustom extends Cors
{
public function beforeAction($action)
{
parent::beforeAction($action);
if (Yii::$app->getRequest()->getMethod() === 'OPTIONS') {
Yii::$app->getResponse()->getHeaders()->set('Allow', 'POST GET PUT');
Yii::$app->end();
}
return true;
}
}
然后
public function behaviors()
{
$behaviors = parent::behaviors();
unset($behaviors['authenticator']);
$behaviors['corsFilter'] = [
'class' => CorsCustom::className(),
];
$behaviors['authenticator'] = [
'class' => HttpBearerAuth::className(),
'optional' => ['login']
];
return $behaviors;
}
“规则”=>[
[
'class'=>'yii\rest\UrlRule',
“控制器”=>[“v1/用户”],
“多元化”=>错误,
“代币”=>[
“{id}”=>”
]
],
[
'class'=>'yii\rest\UrlRule',
'controller'=>['v1/login'=>'/v1/users/login'],
“模式”=>[
'发布'=>'登录',
“选项”=>“选项”,
]
]
],
我也有同样的问题
我就是这样修复的:
我在规则中添加了一个extraPatterns
参数,如下所示:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'pluralize' => false,
'controller' => [
'athlete',
'admin',
'address',
'program'
],
'extraPatterns' => [
'OPTIONS <action:\w+>' => 'options'
]
]
],
],
“urlManager”=>[
“enablePrettyUrl”=>true,
'showScriptName'=>false,
“规则”=>[
[
'class'=>'yii\rest\UrlRule',
“多元化”=>错误,
“控制器”=>[
“运动员”,
“管理员”,
"地址",,
“程序”
],
“外部模式”=>[
“选项”=>“选项”
]
]
],
],
这样,我在这些控制器中的每个自定义操作都将调用
选项
操作。@CreatorR我尝试了您的解决方案,但没有成功,因为我认为您不理解我的问题。。查看rest ActiveController的源代码,我看到为options方法配置了“yii\rest\optionAction”操作。。是否有一种方法可以配置当使用POST调用操作login调用/登录时,以及当使用选项调用/登录时,它调用“yii\rest\optionAction”?实现这一目标的最佳方式是什么?我想这就是我所需要的。@edrian,如果能见到您的urlManager,我将非常高兴rules@edrian,我在选项方面也遇到了同样的问题,但通过声明Cors行为解决了这个问题。目前,我无法重现这种情况来验证我的想法。在此处描述的ActiveController中声明custom
路由的更好方法(使用extraPatterns
configuration)。然后在rest控制器设置未知属性:yii\web\UrlRule::OPTIONS
获取此错误时,您将在何处添加此Cors自定义,你有什么解决办法吗?请检查这个问题:这实际上是唯一帮助我的答案。但我也将其添加到了我使用的身份验证器的“可选”数组中,如下所示:$behaviors['authenticator']=['class'=>\sizeg\jwt\JWTHttpBeareAuth::class',除了'=>['options'],'optional'=>['opt'];
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/users'],
'pluralize' => false,
'tokens' => [
'{id}' => '<id:\\w+>'
]
],
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/login' => '/v1/users/login'],
'patterns' => [
'POST' => 'login',
'OPTIONS' => 'options',
]
]
],
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'pluralize' => false,
'controller' => [
'athlete',
'admin',
'address',
'program'
],
'extraPatterns' => [
'OPTIONS <action:\w+>' => 'options'
]
]
],
],