Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php Yii2 Rest-自定义操作和选项方法_Php_Rest_Yii2 - Fatal编程技术网

Php Yii2 Rest-自定义操作和选项方法

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

我的UsersController类中的以下操作“/login”路由操作有问题

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'
                    ]
                ]
            ],
        ],