Yii2 REST +角跨域CORS [英] Yii2 REST+ Angular Cross Domain CORS

查看:422
本文介绍了Yii2 REST +角跨域CORS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发了Angular& Yii2 REST服务.跨域有问题. 在下面添加我的角度& Yii2 REST代码.

I have developed Angular & Yii2 REST service. Have problem in cross domain. Here below add my angular & Yii2 REST Code.

AngularJs :(例如' http://organization1.example.com ','

AngularJs : (like 'http://organization1.example.com','http://organization2.example.com',....)

$http.defaults.useXDomain = true;
$http.defaults.withCredentials = true;
$http.defaults.headers.common['Authorization'] = 'Bearer ' + MYTOKEN

我从Angular Controller发出的请求:

My Request from Angular Controller:

apiURL = 'http://api.example.com';
$http.get(apiURL + '/roles')
     .success(function (roles) { })
     .error(function () { });

Yii2 .htaccess:(REST URL,例如" http://api.example.com ")

Yii2 .htaccess: (REST URL like 'http://api.example.com')

Header always set Access-Control-Allow-Origin: "*"
Header always set Access-Control-Allow-Credentials: true
Header always set Access-Control-Allow-Methods "POST, GET, PUT, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "Authorization,X-Requested-With, content-type"

Yii2我的行为

public function behaviors() {
    $behaviors = parent::behaviors();
    $behaviors['corsFilter'] = [
        'class' => Cors::className(),
        'cors' => [
            'Origin' => ['*'],
            'Access-Control-Expose-Headers' => [
                'X-Pagination-Per-Page',
                'X-Pagination-Total-Count',
                'X-Pagination-Current-Page',
                'X-Pagination-Page-Count',
            ],
        ],
    ];
    $behaviors['authenticator'] = [
        'class' => HttpBearerAuth::className(),
        'except' => ['options'],
    ];
    $behaviors['contentNegotiator'] = [
        'class' => ContentNegotiator::className(),
        'formats' => [
            'application/json' => Response::FORMAT_JSON,
        ],
    ];

    return $behaviors;
}

问题

从我的角度要求是'GET'方法,但它将变为'OPTIONS'方法&返回401未经授权的错误(CORS).因为未发送请求授权标头.

From my angular request is 'GET' method, but it will goes 'OPTIONS' method & return 401 Unauthorized error(CORS). because the request Authorization header is not send.

推荐答案

更新:

正如@jlapoutre所指出的,现在在官方文档:

As pointed by @jlapoutre, this is now well described in official docs:

向控制器添加跨域资源共享过滤器是一种 比添加上述其他过滤器要复杂一些, 因为必须在身份验证之前应用CORS过滤器 方法,因此与其他方法相比需要稍微不同的方法 过滤器.另外,必须禁用CORS Preflight的身份验证 请求,以便浏览器可以安全地确定请求是否可以 无需发送身份验证即可预先进行 证书.以下显示添加代码所需的代码 yii \ filters \ Cors过滤器扩展到现有的控制器,该控制器从 yii \ rest \ ActiveController:

Adding the Cross-Origin Resource Sharing filter to a controller is a bit more complicated than adding other filters described above, because the CORS filter has to be applied before authentication methods and thus needs a slightly different approach compared to other filters. Also authentication has to be disabled for the CORS Preflight requests so that a browser can safely determine whether a request can be made beforehand without the need for sending authentication credentials. The following shows the code that is needed to add the yii\filters\Cors filter to an existing controller that extends from yii\rest\ActiveController:

use yii\filters\auth\HttpBasicAuth;

public function behaviors()
{
    $behaviors = parent::behaviors();

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

    // add CORS filter
    $behaviors['corsFilter'] = [
        'class' => \yii\filters\Cors::className(),
    ];

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

    return $behaviors;
}


旧答案 (已弃用)

parent::behaviors()合并时存在订购问题.完整详细信息此处.

There is an ordering issue when merging with parent::behaviors(). Full details here.

我建议与父数组合并时不要定义键:

I would recommend not defining keys when merging with parent array:

public function behaviors()
{
    return \yii\helpers\ArrayHelper::merge([
        [
            'class' => \yii\filters\Cors::className(),
            'cors' => [...],
        ],
        [
            'class' => \yii\filters\auth\HttpBearerAuth::className(),
            'except' => ['options'],
        ],
        [
            'class' => ContentNegotiator::className(),
            'formats' => [...],
        ]
    ], parent::behaviors());
}

这篇关于Yii2 REST +角跨域CORS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆