Ngu ngơ học làm web (x40) - CakePHP2 - forgot password, generate code

Tiếp theo của: Ngu ngơ học làm web (x39) - CakePHP2 – Sách bán chạy
-----

Phần x40. CakePHP2 – forgot password, generate code


Xem (clip số 41a– chickenrainshop):

Viết chức năng ‘quên mật khẩu’ (forgot password).

- Xử lý quên mật khẩu (41a)

- Hàm sinh mã generate_code (10":09)

- Xác nhận qua email (12":12)

Quy trình xử lý của chức năng ‘quên mật khẩu’:

Bước 1: Điền email
Bước 2: Xác nhận
Bước 3: Đổi mật khẩu mới
- Tạo form
- Kiểm tra email
- Gửi xác nhận
- Kiểm tra xác nhận
- Hiện form đổi mật khẩu
- Kiểm tra mật khẩu
- Lưu mật khẩu mới

Tạo link để vào trang ‘quên mật khẩu’:

[View\Users\login.ctp]

<div class="controls">
            <?php echo $this->Form->button('Đăng nhập', ['type' => 'submit', 'class' => 'col-lg-2 btn btn-primary']); ?>
            <?php echo $this->Html->link('Bạn quên mật khẩu?', '/quen-mat-khau'); ?>
</div>

Viết route cho link ‘/quen-mat-khau’:

[routes.php]

Router::connect('/sach-moi', ['controller' => 'books', 'action' => 'latest_books']);
Router::connect('/quen-mat-khau', ['controller' => 'users', 'action' => 'forgotPassword']);
Router::connect('/sach-ban-chay', ['controller' => 'books', 'action' => 'bestSelling']);

Viết action forgotPassword():

[UsersController.php]

public function forgotPassword() {
                        $this-set('title_for_layout', 'Quên mật khẩu');
            }

Viết view forgot_password.ctp:

[View\Users\forgot_password.ctp]

<div class="panel panel-info">
            <h4 class="panel-heading"><span class="glyphicon glyphicon-user"></span> Quên mật khẩu</h4>
            <?php echo $this->Flash->render('forgot'); ?>
            <?php echo $this->Form->create('User', ['class' => 'form-horizontal', 'novalidate' => true, 'inputDefaults' => ['label' => false]]); ?>
                        <div class="control-group">
                                    <label class="control-label" for="inputEmail">Email</label>
                                    <div class="controls">
                                                <?php echo $this->Form->input('email', ['placeholder' => 'Điền email của bạn']); ?>
                                    </div>
                        </div>
                        <hr>
                        <div class="control-group">
                                    <div class="controls">
                                    <?php echo $this->Form->button('Cấp lại mật khẩu', ['type' => 'submit', 'class' => 'col-lg-2 btn btn-primary']); ?>
                                    </div>
                        </div>
            <?php echo $this->Form->end(); ?>
</div>

Cho phép action forgotPassword được chạy mà không cần đăng nhập:

[Controller\AppController.php]

public function beforeFilter() {
                        $this->Auth->allow('menu', 'index', 'register', 'forgotPassword');
                        $this->set('userInfo', $this->getUser());
            }

Trong bảng users, tạo thêm trường code, Type: VARCHAR(255), cho phép null.

Viết tiếp action forgotPassword():

            public function forgotPassword() {
                        $this->set('title_for_layout', 'Quên mật khẩu');
                        if ($this->request->is('post')) {
                                    $user = $this->User->findByEmail($this->request->data['User']['email']);
                                    if (!empty($user)) {
                                                // tạo mã xác thực
                                                $code = $this->Tool->generateCode();
                                                // tạo link để người dùng bấm vào
                                                $linkConfirm = 'http://local.chickenrainshop/xac-nhan/'.$code;
                                                // lưu code vào cơ sở dữ liệu
                                                $this->User->id = $user['User']['id'];
                                                $this->User->saveField('code', $code);
                                                $this->Flash->success('Vui lòng kiểm tra hộp thư để xác nhận yêu cầu - '.$linkConfirm, ['params' => ['class' => 'alert alert-success'], 'key' => 'forgot']);
                                    } else {
                                                $this->Flash->error('Email này chưa được đăng kí trên hệ thống', ['params' => ['class' => 'alert alert-error'], 'key' => 'forgot']);
                                    }
                        }
            }

Hàm generateCode() trong [Controller\Component\ToolComponent.php]

public function generateCode() {
                                    $randomNumber = rand(1000000, 9999999);
                                    $code = md5($randomNumber);
                                    return $code;
                        }

Xem (clip số 41b– chickenrainshop):

- Xác thực yêu cầu đổi mật khẩu qua email (41b)

Viết chức năng xác nhận yêu cầu đổi mật khẩu:

[Controller\UsersController.php]

public function confirm($code = null) {
                        $confirm = false;
                        if (!empty($code)) {
                                    $user = $this->User->findByCode($code);
                                    if (!empty($user)) {
                                                $confirm = true;
                                    }
                        }
                        $this->set('confirm', $confirm);
                        $this->set('title_for_layout', 'Yêu cầu đổi mật khẩu mới');
            }

Tạo view cho action confirm():

[View\Users\confirm.ctp]

<div class="panel panel-info">
            <?php if ($confirm): ?>
                        <h4 class="panel-heading"><span class="glyphicon glyphicon-user"> Đổi mật khẩu mới</span></h4>
                        <?php echo $this->element('errors'); ?>
                        <?php echo $this->Flash->render(); ?>
                        <?php echo $this->Form->create('User', ['class' => 'form-horizontal', 'novalidate' => true, 'inputDefaults' => ['label' => false]]); ?>
                        <div class="control-group">
                                    <label class="control-label" for="inputUsername">Mật khẩu mới</label>
                                    <div class="controls">
                                                <?php echo $this->Form->input('password', ['placeholder' => 'Nhập mật khẩu mới', 'error' => false]); ?>
                                    </div>
                        </div>
                        <div class="control-group">
                                    <label class="control-label" for="inputPassword">Xác nhận mật khẩu</label>
                                    <div class="controls">
                                                <?php echo $this->Form->input('confirmPassword', ['placeholder' => 'Xác nhận mật khẩu', 'type' => 'password', 'error' => false]); ?>
                                    </div>
                        </div>
                        <div class="control-group">
                                    <div class="controls">
                                                <?php echo $this->Form->button('Lưu', ['type' => 'submit', 'class' => 'col-lg-2 btn btn-primary']); ?>
                                    </div>
                        </div>
                        <?php echo $this->Form->end(); ?>
            <?php else: ?>
                        Xác nhận sai!
            <?php endif ?>
</div>

Cho phép chức năng confirm được thực thi mà không phải đăng nhập:

[Controller\AppController.php]

public function beforeFilter() {
                        $this->Auth->allow('confirm','menu', 'index', 'register', 'forgotPassword');
                        $this->set('userInfo', $this->getUser());
            }

Route cho link confirm:

[routes.php]


Router::connect('/xac-nhan/:code', ['controller' => 'users', 'action' => 'confirm'], ['pass' => ['code']]);
-----------
Cập nhật 22/7/2017
-----------
Xem thêm:
Tổng hợp các bài viết về Ngu ngơ học làm web