doushanmo7024 2015-11-17 14:57
浏览 97
已采纳

Yii2使用SQLite数据库登录似乎不起作用

I'm pretty frustrated. Already searched the s**t out of Google and SO...

I'm using the basic Yii2 template and try to implement User Login, but can't figure out why it won't log me in.

The problem is, I have to use an already existing database with a horrible structure:

| Category | Subcategory |    Name     |     Value     |
|    ...   |     ...     |    ...      |     ....      |
|     9    |   23712298  |   "Alias"   | "myUsername"  |
|     9    |   23712298  | "Password"  |   "test123"   |
|     9    |   15032862  |   "Alias"   | "myUsername2" |
|     9    |   15032862  | "Password"  |  "test12345"  |
|    ...   |     ...     |    ...      |     ....      |

As you can see, "Alias" = Username and password is a bcrypt hash of the user's password.

And here is my StudyController.php (excerpt):

<?php

namespace app\controllers;

use Yii;
use yii\web\Controller;
use yii\widgets\ListView;
use yii\data\ActiveDataProvider;
use app\models\Study;
use app\models\StudySearch;
use app\models\Image;
use app\models\User;
use app\models\LoginForm;
use yii\filters\AccessControl;
use yii\filters\VerbFilter;

class StudyController extends Controller {
  public function behaviors() {
    return [
        'access' => [
            'class' => AccessControl::className(),
            'only' => ['index', 'show-images', 'logout'],
            'rules' => [
                [
                    'allow' => true, // allow rule
                    'actions' => ['login'], // empty array: deny/allow all
                    'roles' => ['?'], // not authorized / guest
                ],
                [
                    'allow' => true, // allow rule
                    'actions' => ['index', 'show-images', 'logout'],
                    'roles' => ['@'], // logged-in user
                ],
            ],
        ],
        'verbs' => [
            'class' => VerbFilter::className(),
            'actions' => [
                'logout' => ['post'],
            ],
        ],
    ];
  }

public function actionLogin()
{
    if (!\Yii::$app->user->isGuest) {
        return $this->goHome();
        //return $this->redirect('/study/index');
    }

    $model = new LoginForm();
    if ($model->load(Yii::$app->request->post()) && $model->login()) {
        return $this->goHome();
        //return $this->goBack();
    }

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

And here is my LoginForm.php Model:

<?php

namespace app\models;

use Yii;
use yii\base\Model;
use app\models\User;

class LoginForm extends Model
{
    public $username;
    public $password;
    public $rememberMe = true;

    private $_user = false;


    /**
     * @return array the validation rules.
     */
    public function rules()
    {
        return [
            // username and password are both required
            [['username', 'password'], 'required'],
            // rememberMe must be a boolean value
            ['rememberMe', 'boolean'],
            // password is validated by validatePassword()
            ['password', 'validatePassword'],
        ];
    }

    /**
     * Validates the password.
     * This method serves as the inline validation for password.
     *
     * @param string $attribute the attribute currently being validated
     * @param array $params the additional name-value pairs given in the rule
     */
    public function validatePassword($attribute, $params)
    {
        if (!$this->hasErrors()) {
            $user = $this->getUser();

            if (!$user || !$user->validatePassword($this->password)) {
                $this->addError($attribute, 'Incorrect username or password.');
            }
        }
    }

    /**
     * Logs in a user using the provided username and password.
     * @return boolean whether the user is logged in successfully
     */
    public function login()
    {
        if ($this->validate()) {
            return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0);
        }
        return false;
    }

    /**
     * Finds user by [[username]]
     *
     * @return User|null
     */
    public function getUser()
    {
        if ($this->_user === false) {
            $this->_user = User::findByUsername($this->username);
        }

        return $this->_user;
    }
}

And the User Model which implements the IdentityInterface:

<?php

namespace app\models;

use Yii;
use yii\web\IdentityInterface;
use yii\base\NotSupportedException;

/**
 * This is the model class for table "Config".
 */
class User extends \yii\db\ActiveRecord implements IdentityInterface
{
    public static $userID;
    public static $hash;

    public $authKey;

    public static function tableName()
    {
        return 'Config';
    }

    public static function getDb()
    {
        return Yii::$app->dbConfig;
    }

    public function rules()
    {
        return [
            [['username', 'hash'], 'required'],
            [['username', 'hash'], 'string'],
        ];
    }

    public static function findIdentity($id) {
        $sql = 'SELECT DISTINCT a.Subcategory as id, a.Value as username, b.Value AS hash FROM Config as a, Config as b
                    WHERE
                        a.Category=b.Category AND a.Subcategory=b.Subcategory
                        AND a.Category = 9 AND a.Name = "Alias" and b.Name="Password" AND id = :id';

        $user = static::findBySql($sql, [':id' => $id])->one();
        if(!empty($user)) {
            self::$userID = $user->id;
            self::$hash = $user->hash;
        }

        return (!empty($user)) ? new static($user) : null;
    }

    public static function findByUsername($username) {
        $sql = 'SELECT DISTINCT a.Subcategory as id, a.Value as username, b.Value AS hash FROM Config as a, Config as b
                    WHERE
                        a.Category=b.Category AND a.Subcategory=b.Subcategory
                        AND a.Category = 9 AND a.Name = "Alias" and b.Name="Password" AND username = :username';

        $user = static::findBySql($sql, [':username' => $username])->one();

        if(!empty($user)) {
            self::$userID = $user->id;
            self::$hash = $user->hash;
        }

        return (!empty($user)) ? $user : null;
    }

    public static function validatePassword($password) {
        return Yii::$app->getSecurity()->validatePassword($password, self::$hash);
    }

    public function getId() {
        if(empty(self::$userID)) {
            throw new NotSupportedException('getID ist leer'); // just testing
        }
        else {
            return self::$userID;
        }
    }

    public function setId($id) {
        self::$userID = $id;
    }

    public function getHash() {
        return self::$hash;
    }

    public function setHash($hash) {
        self::$hash = $hash;
    }

    public static function findIdentityByAccessToken($token, $type = null) {
        throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
    } 
    public function getAuthKey() {
        //$this->generateAuthKey();
        return $this->authKey;
    }
    public function validateAuthKey($authKey) {
        return $this->getAuthKey() === $authKey;
    }

    public function generateAuthKey() {
        $this->authKey = \Yii::$app->getSecurity()->generateRandomString();
        $this->save();
    }

    public function beforeSave($insert)
    {
        if (parent::beforeSave($insert)) {
            if ($this->isNewRecord) {
                //$this->authKey = \Yii::$app->getSecurity()->generateRandomString();
                $this->generateAuthKey();
            }
            return true;
        }
        return false;
    }
}

And last but not least, the Login View:

<?php

/* @var $this yii\web\View */
/* @var $form yii\bootstrap\ActiveForm */
/* @var $model app\models\LoginForm */

use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use app\models\User;

$this->title = 'Login';
$this->params['breadcrumbs'][] = $this->title;

echo '<pre>';
print_r(Yii::$app->request->post());
echo '</pre>';

echo '<pre>';
print_r(Yii::$app->user->identity);
echo '</pre>';
?>
<div class="site-login">
    <h1><?= Html::encode($this->title) ?></h1>

    <p>Please fill out the following fields to login:</p>

    <?php $form = ActiveForm::begin([
        'id' => 'login-form',
        'options' => ['class' => 'form-horizontal'],
        'fieldConfig' => [
            'template' => "{label}
<div class=\"col-lg-3\">{input}</div>
<div class=\"col-lg-8\">{error}</div>",
            'labelOptions' => ['class' => 'col-lg-1 control-label'],
        ],
    ]); ?>

        <?= $form->field($model, 'username') ?>

        <?= $form->field($model, 'password')->passwordInput() ?>

        <?= $form->field($model, 'rememberMe')->checkbox([
            'template' => "<div class=\"col-lg-offset-1 col-lg-3\">{input} {label}</div>
<div class=\"col-lg-8\">{error}</div>",
        ]) ?>

        <div class="form-group">
            <div class="col-lg-offset-1 col-lg-11">
                <?= Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>
            </div>
        </div>

    <?php ActiveForm::end(); ?>
</div>

When I open the Login Form and insert a valid username and password, it brings me back to the Login Form. Looked into Gii Logs and here is the output: Gii Output As you can see, it obviously logged me in. Still can't go to another subpage..

The cookie "_identity" is there and my own database queries in the User.php Model seem to work fine btw (otherwise the screenshot wouldn't show the right userID).

Here's the user components part of my config:

'components' => [
    'user' => [
        'identityClass' => 'app\models\User',   
        'enableAutoLogin' => true,
        'enableSession' => true,
        'loginUrl' => ['study/login'],
    ],

I really hope you guys can help me, can't figure it out by myself. If you need more details, just hit me up. Can't think of anything else right now.

Much appreciated!

Shayan

  • 写回答

1条回答 默认 最新

  • duangu1033 2015-11-27 13:42
    关注

    I was testing it locally. Turned out that I should have tested it on the server, because everything works fine there.

    Problem was my php.ini: The directory in "session.save_path" didn't exist, so it couldn't save the session.

    Make sure the directory exists and it is writable.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记