Ошибка User::login() must implement interface yii\web\IdentityInterface при аутентификации пользователя

Всё про контроль доступа пользователей: фильтры, RBAC, проверки
Ответить
azz
Сообщения: 197
Зарегистрирован: 2016.07.06, 17:20

Ошибка User::login() must implement interface yii\web\IdentityInterface при аутентификации пользователя

Сообщение azz »

Приветствую. Пытаюсь реализовать возможность логина пользователя в том несложном виде, в каком это реализовано изначально в стандартном примере шаблона advanced. В результате получаю ошибку:

Код: Выделить всё

    "name": "PHP Recoverable Error",
    "message": "Argument 1 passed to yii\\web\\User::login() must implement interface yii\\web\\IdentityInterface, null given, called in C:\\WebServers\\home\\site.local\\frontend\\models\\LoginForm.php on line 31 and defined",
    "code": 4096,
    "type": "yii\\base\\ErrorException",
    "file": "C:\\WebServers\\home\\site.local\\vendor\\yiisoft\\yii2\\web\\User.php",
    "line": 238,
    "stack-trace": [
        "#0 C:\\WebServers\\home\\site.local\\vendor\\yiisoft\\yii2\\web\\User.php(238): yii\\base\\ErrorHandler->handleError(4096, 'Argument 1 pass...', 'C:\\\\WebServers\\\\h...', 238, Array)",
        "#1 C:\\WebServers\\home\\site.local\\frontend\\models\\LoginForm.php(31): yii\\web\\User->login(NULL, 0)",
        "#2 C:\\WebServers\\home\\site.local\\frontend\\controllers\\SiteController.php(185): frontend\\models\\LoginForm->login()",
        "#3 [internal function]: frontend\\controllers\\SiteController->actionLogin()",
        "#4 C:\\WebServers\\home\\site.local\\vendor\\yiisoft\\yii2\\base\\InlineAction.php(57): call_user_func_array(Array, Array)",
        "#5 C:\\WebServers\\home\\site.local\\vendor\\yiisoft\\yii2\\base\\Controller.php(156): yii\\base\\InlineAction->runWithParams(Array)",
        "#6 C:\\WebServers\\home\\site.local\\vendor\\yiisoft\\yii2\\base\\Module.php(523): yii\\base\\Controller->runAction('login', Array)",
        "#7 C:\\WebServers\\home\\site.local\\vendor\\yiisoft\\yii2\\web\\Application.php(102): yii\\base\\Module->runAction('site/login', Array)",
        "#8 C:\\WebServers\\home\\site.local\\vendor\\yiisoft\\yii2\\base\\Application.php(380): yii\\web\\Application->handleRequest(Object(yii\\web\\Request))",
        "#9 C:\\WebServers\\home\\site.local\\frontend\\web\\index.php(24): yii\\base\\Application->run()",
        "#10 {main}"
    ]
контроллер:

Код: Выделить всё

    public function actionLogin() {
//        if (Yii::$app->request->isAjax) {
            \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

            if (!Yii::$app->user->isGuest)
                return ['error' => 'unable_login'];

            $modelLoginForm = new LoginForm();
            if ($modelLoginForm->load(Yii::$app->request->post())) {
                if ($user = $modelLoginForm->login()) {
                    return ['error' => 'ok', 'user_email' => $user->email];
                }
                else
                    return ['error' => 'login_error'] + $modelLoginForm->errors;
            }
//        }
        return $this->redirect(['site/index']);
    }
модель формы:

Код: Выделить всё

namespace frontend\models;

use Yii;
use yii\base\Model;
use common\models\Users;

class LoginForm extends Model {

    public $email,
           $password,
           $rememberMe;

   private $_user;


    public function rules() {
        return [
            [['email', 'password'], 'required', 'message' => 'empty_field'],
            [['email', 'password'], 'trim'],
        ];
    }

    public function login() {
        if ($this->validate())
            return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0); //$this->_user;
        else
            return FALSE;
    }

   /**
     * Finds user by email or id
     *
     * @return User|null
     */
    protected function getUser() {
        if ($this->_user === null) {
            $this->_user =  Users::findByUsername($this->email);
        }

        return $this->_user;
    }
}
модель Users абсолютно идентична оригинальному файлу, кроме того что в названии я дописал "s" с соотв. правкой в других местах.

Опытным путём выяснил, что в оригинале в функции LoginForm->login() при неверных данных (т.е. когда пользователь не найден), функция $this->validate() возвращает false и в $model->errors содержится вот такое:

Код: Выделить всё

{ 
    ["password"]=> array(1) 
        { 
            [0]=> string(31) "Incorrect username or password." 
        
        }        
} 
соотв. вызова "Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0);" не происходит.

у меня же, $this->validate() возвращает true и соотв дальше в Yii::$app->user->login передаётся вместо найденного пользователя null, что и вызывает ошибку. Я пока выкрутился вот так:

Код: Выделить всё

    public function login() {
        if ($this->validate() && !is_null($this->_user = $this->getUser())) {
            if (Yii::$app->user->login($this->_user, $this->rememberMe ? 3600 * 24 * 30 : 0));
                return $this->_user;
        }

        return FALSE;
    }
но осталось стойкое ощущение, что я чего-то недопонял. Можете подсказать, что именно?
Аватара пользователя
zabachok
Сообщения: 522
Зарегистрирован: 2013.12.16, 14:38

Re: Ошибка User::login() must implement interface yii\web\IdentityInterface при аутентификации пользователя

Сообщение zabachok »

azz писал(а): 2017.09.22, 14:58 но осталось стойкое ощущение, что я чего-то недопонял. Можете подсказать, что именно?
Вы недопоняли текста ошибки:
Argument 1 passed to yii\\web\\User::login() must implement interface yii\\web\\IdentityInterface, null given, called in C:\\WebServers\\home\\site.local\\frontend\\models\\LoginForm.php on line 31 and defined
2b||!2b Just read the instructions
webinvader
Сообщения: 12
Зарегистрирован: 2010.09.12, 16:30

Re: Ошибка User::login() must implement interface yii\web\IdentityInterface при аутентификации пользователя

Сообщение webinvader »

Пользователь с такими данными не был найден в бд. Соответственно логинить было некого, поэтому и возникала ошибка
azz
Сообщения: 197
Зарегистрирован: 2016.07.06, 17:20

Re: Ошибка User::login() must implement interface yii\web\IdentityInterface при аутентификации пользователя

Сообщение azz »

zabachok писал(а): 2017.09.22, 15:02
azz писал(а): 2017.09.22, 14:58 но осталось стойкое ощущение, что я чего-то недопонял. Можете подсказать, что именно?
Вы недопоняли текста ошибки:
Argument 1 passed to yii\\web\\User::login() must implement interface yii\\web\\IdentityInterface, null given, called in C:\\WebServers\\home\\site.local\\frontend\\models\\LoginForm.php on line 31 and defined
это к чему? я написал что в моём случае туда подаётся null, чего быть не должно. В моём случае приходится добавлять проверку на null, и всё бы ничего, но в оригинале такой проверки нет.
Аватара пользователя
ElisDN
Сообщения: 5841
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Ошибка User::login() must implement interface yii\web\IdentityInterface при аутентификации пользователя

Сообщение ElisDN »

А зачем Вы убрали метод проверки пароля из LoginForm?
azz
Сообщения: 197
Зарегистрирован: 2016.07.06, 17:20

Re: Ошибка User::login() must implement interface yii\web\IdentityInterface при аутентификации пользователя

Сообщение azz »

ElisDN писал(а): 2017.09.22, 16:36 А зачем Вы убрали метод проверки пароля из LoginForm?
не убрал, я забыл его туда вписать :)
добавил, он ругается "Class validatePassword does not exist"
azz
Сообщения: 197
Зарегистрирован: 2016.07.06, 17:20

Re: Ошибка User::login() must implement interface yii\web\IdentityInterface при аутентификации пользователя

Сообщение azz »

ElisDN писал(а): 2017.09.23, 09:35 Добавьте метод.
так он есть в Users:

Код: Выделить всё

class Users extends ActiveRecord implements IdentityInterface {
..........................
    /**
     * Validates password
     *
     * @param string $password password to validate
     * @return bool if password provided is valid for current user
     */
    public function validatePassword($password) {
        return Yii::$app->security->validatePassword($password, $this->password_hash);
    }
Аватара пользователя
ElisDN
Сообщения: 5841
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Ошибка User::login() must implement interface yii\web\IdentityInterface при аутентификации пользователя

Сообщение ElisDN »

azz писал(а): 2017.09.25, 12:11 так он есть в Users
Это другой. Верните оригинальный метод в LoginForm.
azz
Сообщения: 197
Зарегистрирован: 2016.07.06, 17:20

Re: Ошибка User::login() must implement interface yii\web\IdentityInterface при аутентификации пользователя

Сообщение azz »

ElisDN писал(а): 2017.09.25, 12:41 Это другой. Верните оригинальный метод в LoginForm.
точно, спасибо. А тот что в Users, тогда за что отвечает? Совсем запутался.
Аватара пользователя
ElisDN
Сообщения: 5841
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Ошибка User::login() must implement interface yii\web\IdentityInterface при аутентификации пользователя

Сообщение ElisDN »

azz писал(а): 2017.09.25, 14:59 А тот что в Users, тогда за что отвечает?
Он вызывается из того, который в LoginForm.
Ответить