在yii2中传递持有者令牌会返回错误401

Geo*_*off 9 php rest yii2 typescript2.0 angular

我使用angular2和yii2 restful服务,但它失败了

这是我的角色2部分

In the userservice
 constructor(private http:HttpClientService, private _domaindetails:Domaindetails) { }

profile(val:string="profile"):Observable<User>{
return this.http.get(this.getUserUrl(val))
  .map(this.extractData)

 }
Run Code Online (Sandbox Code Playgroud)

这是httpclientService

 createAuthorizationHeader(headers: Headers) {
  let token = JSON.parse(localStorage.getItem("currentUser")).token;
  if (token) {
    headers.append('Authorization', 'Bearer ' + token);
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    headers.append('Content-Type', 'application/json');
   }

  }

post(url, data) {
  let headers = new Headers();
  this.createAuthorizationHeader(headers);
 return this.http.post(url, data, {
    headers: headers
 });
}
Run Code Online (Sandbox Code Playgroud)

这是我在Yii2的后端

    public function behaviors()
{
    $behaviors = parent::behaviors();
     $behaviors['corsFilter'] = [
        'class' => \yii\filters\Cors::className(),
        'cors' => [
            // restrict access to
            'Origin' => ['http://localhost:4200'],
            'Access-Control-Request-Method' => ['POST', 'GET','PUT'],
            // Allow only POST and PUT methods
            'Access-Control-Request-Headers' => ['*'],
            // Allow only headers 'X-Wsse'
            // 'Access-Control-Allow-Credentials' => true,
            // Allow OPTIONS caching
            'Access-Control-Max-Age' => 3600,
            // Allow the X-Pagination-Current-Page header to be exposed to the browser.
            'Access-Control-Expose-Headers' => ['X-Pagination-Current-Page'],
        ],
    ];

    $auth = $behaviors['authenticator'] = [
        'class' => HttpBearerAuth::className(),
        'only' => ['can-access','profile'],  //access controller
    ];

   $behaviors['authenticator']['except'] = ['options'];
    return $behaviors;
}
Run Code Online (Sandbox Code Playgroud)

并且yii2操作无法返回未经授权的访问错误

 public function actionProfile()
{

    $user = Yii::$app->user->identity;
    return ['data' => $user];
}
Run Code Online (Sandbox Code Playgroud)

当我检查 Yii::$app->request->headers;

在此输入图像描述

如您所见,设置了承载令牌

这是我的用户模型

   public static function findIdentityByAccessToken($token, $type = null)
{
    return static::findOne(['auth_key' => $token]);  //auth_key is the value used in bearer token
}
Run Code Online (Sandbox Code Playgroud)

为什么它继续返回错误401未经授权的访问,但当我使用相同的authkey值并在postman中设置授权承载头时它工作

经过一些研究后,我发现每当angular2发出请求时,它就会发送一个失败的选项请求

Geo*_*off 1

对于那些可能面临这个问题的人,我发现这是由 HttpBearerAuth 引起的,当我更改为QueryParamAuth现在一切正常时,我还做了一些其他更改,如

ON THE CONTROLLER
1.Removed the cors filters

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

    $behaviors['authenticator'] = [
        'class' => CompositeAuth::className(),
        'authMethods' => [
            HttpBasicAuth::className(),
            HttpBearerAuth::className(),
            QueryParamAuth::className(),
        ],
    ];
    return $behaviors;

}
Run Code Online (Sandbox Code Playgroud)

2、在我的配置main.php中

     'response' => [
        'format' => yii\web\Response::FORMAT_JSON,
        'charset' => 'UTF-8',
        'on beforeSend' => function ($event) {
            header("Access-Control-Allow-Origin: *");
        }
    ],
        'urlManager' => [
        'class' => 'yii\web\UrlManager',
        'enablePrettyUrl' => true,
        'showScriptName' => false,
        'rules' => [
            ['class' => 'yii\rest\UrlRule', 'controller' => 'auth', 'pluralize'=>false],
            ...other controlers here
        ],

    ],
Run Code Online (Sandbox Code Playgroud)

3.在项目根目录的.htacess文件中我添加了

   Header set Access-Control-Allow-Origin "*"
   Header set Access-Control-Allow-Headers "Content-Type"
Run Code Online (Sandbox Code Playgroud)

所以我的 angular2 post 请求看起来像

http://127.0.0.1/bcl/api/rest/v1/auth/logout?access-token=your access token
Run Code Online (Sandbox Code Playgroud)

因此访问令牌始终作为查询参数传递

主要原因是因为我发现如果浏览器发送除内容类型之外的任何标头,则会触发选项请求

所以现在我的标题看起来像

headers.append('Content-Type', 'application/x-www-form-urlencoded'); 
//i removed the bearer token
Run Code Online (Sandbox Code Playgroud)