我有一个Yii 2应用程序,我正在从第三方API验证用户,一旦用户通过验证,我就登录用户并设置身份,一切都很好。但当我导航到任何其他页面时,用户身份变为空,用户变成了访客用户。
下面是我的登录表单:
<?php
namespace app\models;
use app\components\RestBehavior;
use app\models\web\LoginIdentity;
use Yii;
use yii\base\Model;
use yii\helpers\Json;
use yii\helpers\VarDumper;
use yii\web\IdentityInterface;
/**
* LoginForm is the model behind the login form.
*
* @property User|null $user This property is read-only.
*
*/
class LoginForm extends Model
{
public $email;
public $password;
public $company_id;
public $companies=[];
public $token;
private $_user = false;
public function behaviors()
{
return [
RestBehavior::class
];
}
/**
* @return array the validation rules.
*/
public function rules()
{
return [
[['email', 'password','company_id'], 'required'],
];
}
/**
* Logs in a user using the provided username and password.
* @return bool whether the user is logged in successfully
*/
public function login()
{
return Yii::$app->user->login($this->getUser(), 0);
}
/**
* Finds user by [[username]]
*
* @return User|null
*/
public function getUser()
{
if ($this->_user === false) {
$this->_user = LoginIdentity::findUser($this->attributes);
}
return $this->_user;
}
}
下面是我的自定义LoginIdentity类:
<?php
namespace app\models\web;
use app\components\RestBehavior;
use \Yii;
use yii\helpers\Json;
use yii\helpers\Url;
use yii\helpers\VarDumper;
class LoginIdentity extends \yii\base\BaseObject implements \yii\web\IdentityInterface
{
public $resource_id;
public $token;
/**
* {@inheritdoc}
*/
public function behaviors()
{
return [
RestBehavior::class
];
}
public static function findUser($params)
{
if(!empty(Yii::$app->user->identity))
{
return new static([
'resource_id'=>self::getId(),
'token'=>self::getAuthKey()
]);
}
else
{
Yii::$app->controller->sendPOST('/login',$params);
if(Yii::$app->response->statusCode===200)
{
$response=Json::decode(Yii::$app->response->data);
$identity=new static([
'resource_id'=>$response['resource']['resource_id'],
'token'=>$response['token']
]);
Yii::$app->session->set('resource_id',$response['resource']['resource_id']);
Yii::$app->session->set('token',$response['token']);
return $identity;
}
return null;
}
}
/**
* {@inheritdoc}
*/
public static function findIdentity($id)
{
$session=Yii::$app->session;
if(!empty($session['resource_id'])&&!empty($session['token']))
{
return new static([
'resource_id'=>$session['resource_id'],
'token'=>$session['token']
]);
}
return null;
}
/**
* {@inheritdoc}
* @param \Lcobucci\JWT\Token $token
*/
public static function findIdentityByAccessToken($token, $type = null)
{
}
/**
* Finds user by username
*
* @param string $username
* @return static|null
*/
public static function findByUsername($username)
{
}
/**
* {@inheritdoc}
*/
public function getId()
{
return $this->resource_id;
}
/**
* {@inheritdoc}
*/
public function getAuthKey()
{
return $this->token;
}
/**
* {@inheritdoc}
*/
public function validateAuthKey($authKey)
{
}
/**
* Validates password
*
* @param string $password password to validate
* @return bool if password provided is valid for current user
*/
public function validatePassword($password)
{
}
}
很奇怪的是,整个代码在我的本地计算机上运行得很好,也就是说在localhost上。但是在服务器上,用户get登录了,但是当他访问任何新的经过验证的路由时就注销了。我已经检查了服务器的/var/lib/php/sessions文件夹,会话被正确地保存了,所以没有权限问题。有人能告诉我这里出了什么问题吗?为什么它在我的本地计算机上运行,而不是远程运行。谢谢。
2条答案
按热度按时间gupuwyp21#
这与Yii2或Identity类的实现无关。代码在任何意义上都是正确的。原因是我的服务器将
cookie_secure
设置为true,这意味着只能在SSL上建立会话,但我试图在不安全的源(即http)上登录。此外,我的网站在SSL上工作,但当页面加载时,由于无效的favicon路径,它变成了不安全或http。因此,火狐浏览器显示在控制台,cookie被拒绝的服务器时,客户端运行在HTTP上,而Chrome的控制台是沉默的幕后发生了什么。kokeuurv2#
感谢Hammad的回答,没有其他人给我一个真实的的解决方案,但我解决了它在“web.php”配置文件,只是改变参数'secure' =〉true为false.原因是,我使用http而不是https(没有SSL),我使用这个临时的解决方案: