Xây dựng chức năng đăng ký và đăng nhập

Tạo bởi Hoàng Vũ, chỉnh sửa cuối lúc 21 tháng 5, 2025

Chức năng đăng ký và đăng nhập người dùng là một phần thiết yếu trong hầu hết các ứng dụng web hiện đại. Yii hỗ trợ quản lý phiên làm việc (session), xác thực người dùng thông qua IdentityInterface và hệ thống User Component. Trong bài học này, học viên sẽ được hướng dẫn cách tạo chức năng đăng ký, đăng nhập và sử dụng "Ghi nhớ đăng nhập" (remember me).

1. Cấu hình hệ thống xác thực người dùng

Trong file config/web.php, cần khai báo identityClass cho component user:

'components' => [
    'user' => [
        'identityClass' => 'app\models\User',
        'enableAutoLogin' => true, // Cho phép ghi nhớ đăng nhập
    ],
]

Model User cần triển khai IdentityInterface.

2. Tạo bảng user trong CSDL

Ví dụ:

CREATE TABLE user (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL UNIQUE,
    password_hash VARCHAR(255) NOT NULL,
    auth_key VARCHAR(32),
    access_token VARCHAR(255)
);

3. Tạo model User

namespace app\models;

use yii\db\ActiveRecord;
use yii\web\IdentityInterface;

class User extends ActiveRecord implements IdentityInterface
{
    public static function findIdentity($id)
    {
        return static::findOne($id);
    }

    public static function findIdentityByAccessToken($token, $type = null)
    {
        return static::findOne(['access_token' => $token]);
    }

    public static function findByUsername($username)
    {
        return static::findOne(['username' => $username]);
    }

    public function validatePassword($password)
    {
        return \Yii::$app->security->validatePassword($password, $this->password_hash);
    }

    public function getId()
    {
        return $this->id;
    }

    public function getAuthKey()
    {
        return $this->auth_key;
    }

    public function validateAuthKey($authKey)
    {
        return $this->auth_key === $authKey;
    }
}

4. Tạo Form đăng ký

Tạo model SignupForm:

namespace app\models;

use yii\base\Model;

class SignupForm extends Model
{
    public $username;
    public $password;

    public function rules()
    {
        return [
            [['username', 'password'], 'required'],
            ['username', 'unique', 'targetClass' => User::class],
        ];
    }

    public function signup()
    {
        if (!$this->validate()) {
            return null;
        }

        $user = new User();
        $user->username = $this->username;
        $user->password_hash = \Yii::$app->security->generatePasswordHash($this->password);
        $user->auth_key = \Yii::$app->security->generateRandomString();

        return $user->save() ? $user : null;
    }
}

5. Tạo Form đăng nhập

Tạo model LoginForm:

namespace app\models;

use yii\base\Model;
use Yii;

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

    private $_user;

    public function rules()
    {
        return [
            [['username', 'password'], 'required'],
            ['rememberMe', 'boolean'],
            ['password', 'validatePassword'],
        ];
    }

    public function validatePassword($attribute)
    {
        $user = $this->getUser();
        if (!$user || !$user->validatePassword($this->password)) {
            $this->addError($attribute, 'Sai tên đăng nhập hoặc mật khẩu.');
        }
    }

    public function getUser()
    {
        if ($this->_user === null) {
            $this->_user = User::findByUsername($this->username);
        }
        return $this->_user;
    }

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

6. Controller xử lý đăng ký và đăng nhập

Đăng ký

public function actionSignup()
{
    $model = new SignupForm();

    if ($model->load(Yii::$app->request->post()) && $model->signup()) {
        Yii::$app->session->setFlash('success', 'Đăng ký thành công.');
        return $this->redirect(['login']);
    }

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

Đăng nhập

public function actionLogin()
{
    if (!Yii::$app->user->isGuest) {
        return $this->goHome();
    }

    $model = new LoginForm();

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

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

7. View đơn giản cho đăng ký và đăng nhập

Form đăng nhập

<?php $form = ActiveForm::begin(); ?>

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

<div class="form-group">
    <?= Html::submitButton('Đăng nhập', ['class' => 'btn btn-primary']) ?>
</div>

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

Ví dụ cụ thể

Giả sử bạn xây dựng một hệ thống cho phép người dùng đăng ký tài khoản bằng tên đăng nhập và mật khẩu, sau đó đăng nhập với thông tin đó. Tài khoản được lưu trong bảng user. Khi đăng nhập, hệ thống sử dụng Yii::$app->user để xác thực và lưu thông tin người dùng trong session, đồng thời hỗ trợ ghi nhớ người dùng bằng cookie khi rememberMe được chọn.

Kết luận

Việc xây dựng chức năng đăng ký và đăng nhập là nền tảng cho mọi ứng dụng có hệ thống người dùng. Yii cung cấp cơ chế mạnh mẽ và an toàn cho việc xác thực thông qua IdentityInterfaceUser Component. Khi được triển khai đúng cách, bạn có thể đảm bảo sự bảo mật, tiện lợi và khả năng mở rộng cho hệ thống xác thực người dùng.

Website Logo

Với hơn 10 năm kinh nghiệm lập trình web và từng làm việc với nhiều framework, ngôn ngữ như PHP, JavaScript, React, jQuery, CSS, HTML, CakePHP, Laravel..., tôi hy vọng những kiến thức được chia sẻ tại đây sẽ hữu ích và thiết thực cho các bạn.

Bình luận

Website Logo

Chào, tôi là Vũ. Đây là blog hướng dẫn lập trình của tôi.

Liên hệ công việc qua email dưới đây.

lhvuctu@gmail.com

Chúng Tôi Trên

Bạn đang muốn học về lập trình website?

Bạn cần nâng cao kiến thức chuyên nghiệp hơn để nâng cao cơ hội nghề nghiệp? Liên hệ