Passar o token portador em yii2 rest retorna um erro de 401

9

Estou usando serviços repousantes angular2 e yii2, mas ele falha

Esta é a minha parte 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)

 }

Este é o 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
 });
}

Este é o meu back-end em 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;
}

E a ação yii2 falha ao retornar um erro de acesso não autorizado

 public function actionProfile()
{

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

Quando eu verifico Yii::$app->request->headers;

Como você pode ver, o token do portador está definido

Este é o meu usermodel

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

Por que ele continua retornando um erro de acesso não autorizado 401 e ainda quando eu uso o mesmo valor de authkey e defino cabeçalhos de portador de autorização no carteiro funciona

Após algumas pesquisas, descobri que sempre que o angular2 faz um pedido, ele envia uma solicitação de opções que falha

    
por GEOFFREY MWANGI 23.01.2017 в 08:07
fonte

2 respostas

1

Para aqueles que podem enfrentar este problema eu descobri que isso foi causado pelo HttpBearerAuth e quando mudei para QueryParamAuth tudo está funcionando agora eu também fiz algumas outras mudanças como

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, na minha configuração 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
        ],

    ],

3.No arquivo .htacess na raiz do projeto, adicionei

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

Então, meu pedido de postagem angular2 parece

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

Assim, o token de acesso é sempre passado como um parâmetro de consulta

A razão principal é porque descobri que, se o navegador enviar qualquer cabeçalho para além do tipo de conteúdo, um pedido de opções é acionado

Então agora meus cabeçalhos parecem

headers.append('Content-Type', 'application/x-www-form-urlencoded'); 
//i removed the bearer token
    
por GEOFFREY MWANGI 26.01.2017 / 09:16
fonte
1

Eu usei uma abordagem diferente:

Adicionado

    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;
    }

no controlador.

Manteve a função de comportamentos conforme sua pergunta.

Como você mencionou, o problema é que o navegador envia uma solicitação pré-impressa.

Minha suposição é que você está fazendo uma solicitação entre navegadores (localhost: 4200), portanto o navegador está fazendo uma solicitação OPTIONS primeiro ao servidor para descobrir as configurações "Access-Control-Allow", mas sem um token de acesso no cabeçalho. Então, um 401 é lançado e o processo CORS é interrompido.

A diferença é que, dessa forma, você pode ter o token de autorização em um cabeçalho.

    
por Jannes Botis 26.01.2017 / 12:04
fonte