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

时间:2015-11-17 14:57:02

标签: php sqlite authentication login yii2

我非常沮丧。已经搜索过Google和SO ...

我正在使用基本的Yii2模板并尝试实现用户登录,但无法弄清楚为什么它不会让我登录。

问题是,我必须使用一个结构糟糕的现有数据库:

""

如您所见,| Category | Subcategory | Name | Value | | ... | ... | ... | .... | | 9 | 23712298 | "Alias" | "myUsername" | | 9 | 23712298 | "Password" | "test123" | | 9 | 15032862 | "Alias" | "myUsername2" | | 9 | 15032862 | "Password" | "test12345" | | ... | ... | ... | .... | =用户名和"Alias"是用户密码的bcrypt哈希值。

这是我的StudyController.php(摘录):

password

这是我的LoginForm.php模型:

<?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,
    ]);
}

实现IdentityInterface的用户模型:

<?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;
    }
}

最后但并非最不重要的是,登录视图:

<?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;
    }
}

当我打开登录表单并插入有效的用户名和密码时,它会将我带回登录表单。 查看Gii Logs,输出结果如下:Gii Output 正如你所看到的,它显然让我进入了。仍然无法进入另一个子页面..

cookie“_identity”在那里,我在User.php模型中的数据库查询似乎工作正常btw(否则屏幕截图不会显示正确的用户ID)。

以下是我配置的用户组件部分:

<?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}\n<div class=\"col-lg-3\">{input}</div>\n<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>\n<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>

我真的希望你们能帮助我,不能自己解决。如果您需要更多细节,请点击我。现在想不出别的什么。

非常感谢!

砂眼

1 个答案:

答案 0 :(得分:0)

我在本地测试它。原来我应该在服务器上测试它,因为那里的一切都很好。

问题是我的php.ini:“session.save_path”中的目录不存在,因此无法保存会话。

确保目录存在且可写。