There are a number of threads in this forum covering an apparently successful login which disappears on the next call from browser to webserver. Causes are various, such as the identity object not implementing \yii\web\IdentityInterface
and incorrect configuration in web.php components. I’ve checked my code and can’t see any of those problems. Like others, hours have been spent, so I suggest that Yii needs to report problems with authentication a bit better - especially as authentication is often where one starts with a new app. (I have some Yii 1.1 apps running, this is my first Yii2 app).
I want session based login (with no autoLogin, i.e. no persistence between sessions). All PHP calls are XHR calls, the app loads index.html.
from web.php:
'user' => [
'identityClass' => 'app\models\Brokers',
'enableAutoLogin' => false,
'enableSession' => true,
],
The Brokers class includes:
namespace app\models;
use Yii;
class Brokers extends \yii\db\ActiveRecord implements \yii\web\IdentityInterface
{
public static function findIdentity($id)
{
return static::findOne(['dbBrokerNo' => $id, 'dbRejectBroker'=>0]);
}
public static function findIdentityByAccessToken($token, $type = null)
{
throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
}
public static function findByUsername($username)
{
return static::findOne(['dbBrokerCode' => $username, 'dbRejectBroker' => 0]);
}
public function getId()
{
return $this->dbBrokerNo;
}
public function getAuthKey()
{
throw new NotSupportedException('"getAuthKey" is not implemented.');
}
public function validateAuthKey($authKey)
{
throw new NotSupportedException('"validateAuthKey" is not implemented.');
}
public static function tableName()
{
return 'Brokers';
}
With the rest as generated by gii.
Below is my login Class, the "ping" action is used to demonstrate the problem - identity etc is null
namespace app\controllers;
use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\filters\VerbFilter;
use app\models\Brokers;
use yii\web\User;
use yii\helpers\Json;
class LoginController extends AjaxController
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout','login','ping'],
'rules' => [
[
'actions' => ['logout'],
'allow' => true,
'roles' => ['?'],
'verbs' => ['POST']
],
[
'actions' => ['login'],
'allow' => true,
'roles' => ['?'],
'verbs' => ['POST']
],
[
'actions'=>['ping'],
'allow'=>true,
'roles'=>['?'],
'verbs' => ['POST']
]
],
'denyCallback' => function ($rule, $action) {
throw new \Exception('You are not allowed to access this page');
}
]
];
}
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
]
];
}
public function actionLogin(){
$returns = [];
$session = Yii::$app->session;
$session->open();
$user = \app\models\Brokers::findByUsername( $this->json->username );
if( $user && $user->dbPassword === $this->json->password ) {
Yii::$app->user->login( $user ); // $this->rememberMe ? 3600 * 24 * 30 : 0
$returns[ 'accessLevel' ] = $user->dbAccessLevel;
$returns[ 'getid' ] = Yii::$app->user->getId();
$returns[ 'identity' ] = Yii::$app->user->identity;
}
$this->returns( $returns );
}
public function actionPing(){
$returns = [
'getid'=>Yii::$app->user->getId(),
'id' => Yii::$app->user->id,
'identity' => Yii::$app->user->identity
];
$this->returns( $returns );
}
public function actionLogout(){
Yii::$app->user->logout();
$this->returns();
}
}
and the class being extended by LoginController is:
namespace app\controllers;
use Yii;
use yii\web\Controller;
use yii\helpers\Json;
use yii\base\InvalidConfigException;
class AjaxController extends \yii\web\Controller {
public $json;
public function beforeAction($event)
{
$this->enableCsrfValidation = false;
$this->json = Json::decode(file_get_contents("php://input"), false);
header('content-type: application/json');
return parent::beforeAction($event);
}
public function returns( $returns = [] )
{
$returns['isAuthenticated'] = ! Yii::$app->user->getIsGuest();
echo Json::encode ( $returns );
}
}