phprestyii2

How to login user using rest API in yii2


I new in yii2, I want login user using rest API but unable to do this. I have setup basic REST API from this blog:

budiirawan.com/setup-restful-api-yii2/

After that I have created :

api\modules\v1\controllers\SiteController.php

<?php
namespace api\modules\v1\controllers;

use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use common\models\LoginForm;
use yii\filters\VerbFilter;
use yii\rest\ActiveController;
/**
 * Site controller
 */
class SiteController extends ActiveController
{
    /**
     * @inheritdoc
     */
    public $modelClass = 'api\modules\v1\models\user';    

 
    public function actionIndex()
    {
            if (!\Yii::$app->user->isGuest) {
            return $this->goHome();
        }

        $model = new LoginForm();
        if ($model->load(Yii::$app->request->post()) && $model->login()) {
            return $this->goBack();
        } else {
            return $this->render('login', [
                'model' => $model,
            ]);
        }
    }

    public function actionLogout()
    {
        Yii::$app->user->logout();

        return $this->goHome();
    }
}

And Created Model

RtWorkForce\api\modules\v1\models\User.php

<?php
namespace api\modules\v1\models;
use \yii\db\ActiveRecord;

/**
 * User Model
 *
 */
class User extends ActiveRecord
{
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return '{{%user}}';
        
    }

    
}

Here Is my 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' => [ 
                'request' => [
                    'parsers' => [
                        'application/json' => 'yii\web\JsonParser',
                    ]
                ],  
        'user' => [
            'identityClass' => 'common\models\User',
            'enableAutoLogin' => false,
        ],
        'log' => [
            'traceLevel' => YII_DEBUG ? 3 : 0,
            'targets' => [
                [
                    'class' => 'yii\log\FileTarget',
                    'levels' => ['error', 'warning'],
                ],
            ],
        ],
        'urlManager' => [
            'enablePrettyUrl' => true,
            'enableStrictParsing' => true,
            'showScriptName' => false,
            'rules' => [
                [
                    'class' => 'yii\rest\UrlRule', 
                    'controller' => ['v1/country','v1/user','v1/site'],
                    'tokens' => [
                        '{id}' => '<id:\\w+>'
                    ]
                    
                ]
            ],        
        ]
    ],
    'params' => $params,
];

But it's not working and I don't know where I am wrong?


Solution

  • From Yii 2.0 REST Authentication docs :

    Unlike Web applications, RESTful APIs are usually stateless, which means sessions or cookies should not be used.

    And from this other docs about the user class which implement yii\web\IdentityInterface :

    if your application is a pure stateless RESTful application, you would only need to implement findIdentityByAccessToken() and getId() while leaving all other methods with an empty body.


    RESTfull is about routing. If following a token based authentication, then, It should return a resources or a collections if the request sent to server is holding a valid token. Otherwise it should be rejected.

    Login process in that case, is one request holding a username/password pair that will be exchanged with a valid token by server, that is the token you are going to include with all your next requests.

    If session is disabled on server side by setting enableSession to false as described in Yii documentation (see links above) and as recommended by the stateless nature of REST, then \Yii::$app->user->isGuest should not provide info as your server won't have any session to get it from. (unless it verifies token validity instead of checking session)

    When building a class extending yii\rest\ActiveController you can't render a html page like :

    return $this->render('login', [
        'model' => $model,
    ]);
    

    or redirect to a different HTML page like :

    return $this->goHome();
    

    That will work with a yii\base\Controller when building a HTML based web app instead of yii\rest\ActiveController. with ActiveController you just return data which will be serialized to json or xml before output.

    Please refer to Yii RESTful API framework documentations for more details. Then you may find useful information in this great tutorial on How to implement Yii2 REST Authentication :

    http://blog.neattutorials.com/angularjs-and-yii2-part-2-authentication/