Передача токена носителя в Yii2 rest возвращает ошибку 401

Я использую службы Angular2 и Yii2 restful, но это не удается

это моя angular2 часть

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)

 }

это 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
 });
}

это мой бэкэнд в Yii2

    public function behaviors()
{
    $behaviors = parent::behaviors();
     $behaviors['corsFilter'] = [
        'class' => yiifiltersCors::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;
}

и действие yii2 не возвращает ошибку несанкционированного доступа

 public function actionProfile()
{

    $user = Yii::$app->user->identity;
    return ['data' => $user];
}

при проверке Yii::$app->request->headers;

enter image description here

как вы можете видеть, токен носителя установлен

это мой usermodel

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

почему он продолжает возвращать ошибку 401 несанкционированный доступ, и все же, когда я использую то же значение authkey и устанавливаю заголовки носителей авторизации в postman, он работает

после нескольких исследований я узнал, что всякий раз, когда angular2 делает запрос, он отправляет запрос опций, который терпит неудачу

2 ответов


для тех, кто может столкнуться с этой проблемой, я узнал, что это было вызвано 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;

}

2,в моей конфигурации главных.в 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
        ],

    ],

3.В ... htacess файл в корне проекта я добавил

   Header set Access-Control-Allow-Origin "*"
   Header set Access-Control-Allow-Headers "Content-Type"

таким образом, мой запрос Angular2 post выглядит как

http://127.0.0.1/bcl/api/rest/v1/auth/logout?access-token=your access token

так что маркер доступа всегда передается в качестве параметра запроса

в основная причина в том, что я узнал, что если браузер отправляет какой-либо заголовок, кроме типа контента, запускается запрос опций

Итак, теперь мои заголовки выглядят как

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

я использовал другой подход:

добавил

    public function beforeAction($action)
    {
        $this->enableCsrfValidation = false;
        parent::beforeAction($action);

        if (Yii::$app->getRequest()->getMethod() === 'OPTIONS') {
            // End it, otherwise a 401 will be shown.
            Yii::$app->end();
        }

        return true;
    }

в контроллере.

сохранил функцию поведения, как в вашем вопросе.

Как вы упомянули, проблема в том, что браузер отправляет предварительный запрос.

мое предположение заключается в том, что вы делаете запрос кросс-браузера(localhost:4200), поэтому браузер сначала делает запрос опций на сервер, чтобы узнать настройки "Access-Control-Allow", но без доступа маркер в заголовке. Так что 401 бросается, и процесс ПДБС прерывается.

разница в том, что таким образом, вы можете иметь маркер авторизации в заголовке.