Yii2 Rest Api Doesn't Return Expected Results

'm trying to create a simple REST API with authentication. But, something is wrong.

I’m using the advanced template with Yii Framework 2. I never had programed for yii before, so I’m learning. Thanks… ;)

My code:

~/api -->config --> main.php




<?php


$params = array_merge(

    require(__DIR__ . '/../../common/config/params.php'),

    require(__DIR__ . '/../../common/config/params-local.php'),

    require(__DIR__ . '/params.php'),

    require(__DIR__ . '/params-local.php')

);


return [

    'id' => 'app-api',

    'basePath' => dirname(__DIR__),    

    'bootstrap' => ['log'],

    'modules' => [

        'v1' => [

            'basePath' => '@app/modules/v1',

            'class' => 'api\modules\v1\Module'

        ]

    ],

    'components' => [        

        'user' => [

            'identityClass' => 'common\models\User',

            'enableAutoLogin' => false,

        ],

        'log' => [

            'traceLevel' => YII_DEBUG ? 3 : 0,

            'targets' => [

                [

                    'class' => 'yii\log\FileTarget',

                    'levels' => ['error', 'warning'],

                ],

            ],

        ],

        'request' => [

            'class' => '\yii\web\Request',

            'enableCookieValidation' => false,

            'parsers' => [

                'application/json' => 'yii\web\JsonParser',

            ],

        ],        

        'urlManager' => [

            'enablePrettyUrl' => true,

            'enableStrictParsing' => true,

            'showScriptName' => false,

            'rules' => [

                [

                    'class' => 'yii\rest\UrlRule', 

                    'controller' => 'v1/teste',

                    'extraPatterns' => [

                            'GET testando' => 'testando',

                        ],

                ],

                [

                    'class' => 'yii\rest\UrlRule',

                    'controller' => 'v1/user',

                    'extraPatterns' => [

                            'GET login' => 'login',

                        ],

                ],

                'OPTIONS v1/user/login' => 'v1/user/login',

                'POST v1/user/login' => 'v1/user/login',

            ],        

        ]

    ],

    'params' => $params,

];



–> modules --> v1 --> controllers --> TesteController.php




<?php

namespace api\modules\v1\controllers;

//Formato json

use yii\filters\ContentNegotiator;

use yii\web\Response;

//Banco de dados

use yii\db\ActiveRecord;


//Segurança

use yii\filters\auth\CompositeAuth;

use yii\filters\auth\HttpBasicAuth;


//Rest api

use yii\rest\ActiveController;


class TesteController extends ActiveController

{

    public $modelClass = 'api\modules\v1\models\Teste';


    public function behaviors()

    {

        $behaviors = parent::behaviors();

        $behaviors['authenticator'] = [

            'class' => HttpBasicAuth::className(), 

        ];  

        $behaviors['bootstrap'] = [

            'class' => ContentNegotiator::className(),

        'formats' => [

            'application/json' => Response::FORMAT_JSON,

        ],

    ];  

        return $behaviors;  

    }


    public function actionTestando(){

        echo "testado";

    }


}



–> modules --> v1 --> controllers --> UserController.php




<?php

namespace api\modules\v1\controllers;


use common\models\LoginForm;

use yii\rest\ActiveController;


class UserController extends ActiveController

{

    public $modelClass = 'common\models\User';


    public function actionLogin()

    {

        $model = new LoginForm();


        if ($model->load(\Yii::$app->getRequest()->getBodyParams(), '') && $model->login()) {

            echo \Yii::$app->user->identity->getAuthKey();

        } else {

            return $model;

        }

    }


    public function actionIndex()

    {

        if (\Yii::$app->user->isGuest) {

            throw new \HttpHeaderException();

        }

        return \Yii::$app->user->getId();

    }

}



–> modules --> v1 --> models --> Teste.php




<?php


namespace api\modules\v1\models;


use yii\behaviors\TimestampBehavior;


use \yii\db\ActiveRecord;


class Teste extends ActiveRecord 

{

    /**

     * @inheritdoc

     */

    public static function tableName()

    {

        return '{{%teste}}';

    }


    /**

     * @inheritdoc

     */

    public function behaviors()

    {

        return [

            TimestampBehavior::className(),

        ];

    }

}



–> modules --> v1 --> models --> User.php




<?php


namespace api\modules\v1\models;


use common\models\User as CommonUser;


class User extends CommonUser{}


--> modules --> v1 --> Module.php


<?php

namespace api\modules\v1;


class Module extends \yii\base\Module

{

    public $controllerNamespace = 'api\modules\v1\controllers';


    public function init()

    {

        parent::init();        

    }

}



Then when I’m testing the REST API with:


curl -D- -u admin:123mudar! -H "Content-Type:application/json" 'domain.com/v1/testa/api/web/v1/testes'

I’ve got (using terminal or browser --> and the browser asks for username and password infinitely):




HTTP/1.1 401 Unauthorized

Date: Mon, 18 Aug 2014 22:44:10 GMT

Server: Apache

Transfer-Encoding: chunked

Content-Type: application/json; charset=UTF-8


{"type":"yii\\web\\UnauthorizedHttpException","name":"Unauthorized","message":"You are requesting with an invalid access token.","code":0,"status":401}



Database table structure:




CREATE TABLE IF NOT EXISTS `teste` (

  `codigo` int(11) NOT NULL AUTO_INCREMENT,

  `nome` varchar(100) NOT NULL,

  PRIMARY KEY (`codigo`),

  KEY `nome` (`nome`)

) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;


INSERT INTO `teste` (`codigo`, `nome`) VALUES

(1, 'valor 1'),

(2, 'valor 2');


CREATE TABLE IF NOT EXISTS `user` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `username` varchar(255) NOT NULL,

  `auth_key` varchar(32) NOT NULL,

  `password_hash` varchar(255) NOT NULL,

  `password_reset_token` varchar(255) DEFAULT NULL,

  `email` varchar(255) NOT NULL,

  `role` smallint(6) NOT NULL DEFAULT '10',

  `status` smallint(6) NOT NULL DEFAULT '10',

  `created_at` int(11) NOT NULL,

  `updated_at` int(11) NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2;


INSERT INTO `user` (`id`, `username`, `auth_key`, `password_hash`, `password_reset_token`, `email`, `role`, `status`, `created_at`, `updated_at`) VALUES

(1, 'admin', '79UF7P3XNV9t075lv1kA8G3mYVaysaIw', '$2y$13$A8x5bNgFSwyN6RTFtgZ2h.oGu87gWqiRrci/jZYzT.KwF6o6sLTzC', NULL, 'admin@admin.com', 10, 10, 1408061655, 1408061655);



The code was attached, just to make it more easy to reproduce, or even to read.

Unzip the folder into advanced template root, at same level the folders "backend and frontend".

The following alias must be added to aliases.php under ~/common/config/

Yii::setAlias(‘api’, dirname(dirname(DIR)) . ‘/api’);

;)