繁体   English   中英

Yii2 + restapi + cors + bearer - 在创建自定义控制器操作时未经授权

[英]Yii2 + restapi + cors + bearer - unauthorized when creating custom controller action

我正在制作角度2 / Yii2应用程序

当我从带有承载标题的Postman调用自定义控制器/动作时,一切正常,但是当我使用来自angular 2应用程序(localhost:4200)的相同标头调用它时,我总是得到Unauthorized 401错误。 当我执行标准操作时,例如来自指南中的示例:

GET /users: list all users page by page;
POST /users: create a new user;

一切正常,只有当我创建自定义动作时,才会被我未经授权。

这是跨域应用程序,angular可在web.example.com上获得,yii2 app在srv.example.com上

namespace app\controllers\restapi;

use yii\filters\auth\CompositeAuth;
use yii\filters\auth\HttpBearerAuth;

class SearchOrderController extends \yii\rest\Controller
{
    public $modelClass = 'app\models\Order';
    public function behaviors()
    {
        $behaviors = parent::behaviors();
        $auth = $behaviors['authenticator'];
        unset($behaviors['authenticator']);
        $behaviors['corsFilter'] = [
                'class' => \yii\filters\Cors::className(),
        ];
        $behaviors['authenticator'] = [
                'class' => CompositeAuth::className(),
                'authMethods' => [
                        HttpBearerAuth::className(),
                ],
        ];
        // avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method)
        return $behaviors;
    }
    public function actionSearch(){
        \Yii::$app->response->format=\yii\web\Response::FORMAT_JSON;
        return ['index'=>'some text', 'value'=>123];
    }
}

我的网址管理员:

        [
            'class' => 'yii\rest\UrlRule',
            'controller' => 'order',
            'pluralize' => false,
            'extraPatterns' => [
                'GET order/<id:\id+>' => 'order/view',
            ]
        ],
        [
            'class' => 'yii\rest\UrlRule',
            'controller' => 'search-order',
            'pluralize' => false,
            'extraPatterns' => [
                'GET search-order/search' => 'search-order/search',
        ]

我使用此处发布的解决方案解决了我的问题:

Yii2 Rest - 自定义动作和OPTIONS方法

并实现自定义Cors类:

<?php 
namespace app\components;

use Yii;
use yii\filters\Cors;

class CustomCors 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();

        // remove authentication filter
        $auth = $behaviors['authenticator'];
        unset($behaviors['authenticator']);

        // add CORS filter
        $behaviors['corsFilter'] = [
                'class' =>CustomCors::className()
        ];

        // re-add authentication filter
        $behaviors['authenticator'] = [
                'class' => CompositeAuth::className(),
                'authMethods' => [
                        HttpBearerAuth::className(),
                ],

        ];

        return $behaviors;
   }

它看起来像是一个预检请求问题。 我在这里看到两件事要解决。

首先,当您扩展yii\\rest\\Controller需要实现响应该请求的操作。 这样的动作已由Yii实现,但在其子控制器yii\\rest\\ActiveController 所以要么你使用actions()函数来导入它就像在这里完成一样,或者你可以直接实现它,因为它在这个其他的satck溢出帖子中完成:

Post Post在Postman中工作,但在Angular 2 app中返回Preflight错误

然后你需要定义他们的相关规则:

[
    'class' => 'yii\rest\UrlRule',
    'controller' => 'order',
    'pluralize' => false,
    'extraPatterns' => [
        'GET order/<id:\id+>' => 'order/view',
        'OPTIONS order/<id:\id+>' => 'order/options',
    ]
],
[
    'class' => 'yii\rest\UrlRule',
    'controller' => 'search-order',
    'pluralize' => false,
    'extraPatterns' => [
        'GET search-order/search' => 'search-order/search',
        'OPTIONS search-order/search' => 'search-order/options',
]

接下来,您需要让您的身份验证允许预检请求,因为浏览器不会发送任何令牌。 通过添加此行,如官方文档中所示:

// avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method)
$behaviors['authenticator']['except'] = ['options'];

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM