I'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.
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\QueryParamAuth;
//Rest api
use yii\rest\ActiveController;
/**
* Country Controller API
*
* @author Budi Irawan <[email protected]>
*/
class TesteController extends ActiveController
{
public $modelClass = 'api\modules\v1\models\Teste';
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => QueryParamAuth::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" 'http://www.domain.com/v1/testa/api/web/v1/testes'
I've got:
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}
Even when I'm using the restClient plugin. What is missing?
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, '[email protected]', 10, 10, 1408061655, 1408061655);