'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’);