Cakephp 3 Hướng dẫn phần Users

Ở bài đầu tiên khi tạo database chúng ta cũng đã tạo table users để thực hiện quản lý cms một cách cơ bản nhất, vì vậy ở bài này chúng ta sẽ sử dụng table users đó để thực hiện trang login, logout, quản lý bài viết…

Tương tự như articles hay tags, chúng ta cũng tạo ra các file cần thiết, có thể sử dụng Composer hoặc làm trực tiếp tạo từng file cũng được. Mình cũng có để source code, nhưng không khuyến kích lấy của mình nhá, làm mới nhớ được.

Sử dụng Composer để tạo: bin/cake bake all users

Sau khi chạy thành công đoạn trên truy cập thử url: http://localhost:8888/cakephp_3_7_2/users, để xem danh sách user đang có.

Các bạn để ý có cột Password, nó hiển thị là sekret đây chính là pass của user, nhưng để như thế thì không được, khi liên quan đến password chúng ta buộc phải mã hoá nó đi. Về mã hoá thì có nhiều chuẩn để mã hoá, ở đây mình sử dụng cái mặc định trong CakePHP là bcrypt , các bạn có thể sử dụng SHA-1 or MD5.

Khi người dùng nhập password của họ, chúng ta sẽ lấy chuỗi nhập đó và mã hoá thông qua Entity của Model User, thêm đoạn mã hoá sau trong src/Model/Entity/User.php: 


<?php
namespace App\Model\Entity;

use Cake\Auth\DefaultPasswordHasher; // Add this line
use Cake\ORM\Entity;

class User extends Entity
{

// Code from bake.

// Add this method
protected function _setPassword($value)
{
if (strlen($value)) {
$hasher = new DefaultPasswordHasher();

return $hasher->hash($value);
}
}
}

Bây giờ, bạn vào lại list users và edit user đang có rồi cập nhật mật khẩu mới thì bạn sẽ nhận ra password đã được mã hoá khi xem lại.

Thêm phần Login

Ở đây chúng ta sẽ sử dụng Components AuthComponent , thêm AuthComponent vào AppController.php 


// In src/Controller/AppController.php
namespace App\Controller;

use Cake\Controller\Controller;

class AppController extends Controller
{
public function initialize()
{
// Existing code

$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'fields' => [
'username' => 'email',
'password' => 'password'
]
]
],
'loginAction' => [
'controller' => 'Users',
'action' => 'login'
],
//use isAuthorized in Controllers
'authorize' => ['Controller'],
// If unauthorized, return them to page they were just on
'unauthorizedRedirect' => $this->referer()
]);

// Allow the display action so our PagesController
// continues to work. Also enable the read only actions.
$this->Auth->allow(['display', 'view', 'index']);
}
public function isAuthorized($user)
{
// Any registered user can access public functions
if (!$this->request->getParam('prefix')) {
return true;
}
// Default deny
return false;
}
}

Phần trên có đoạn


'authenticate' => [
'Form' => [
'fields' => [
'username' => 'email',
'password' => 'password'
]
]
],

Nó dùng để xác định field nào ở table users để đăng nhập, ở ví dụ của chúng ta không sử dụng username mà sử dụng email + password để đăng nhập.

Tiếp theo đoạn sau là để xác định controller và action nào form đăng nhập


'loginAction' => [
'controller' => 'Users',
'action' => 'login'
],

Ở dòng $this->Auth->allow([‘display’, ‘view’, ‘index’]); xác định action nào không cần đăng nhập vẫn có thể truy cập, nó đồng nghĩa với việc nếu bây giờ khi truy cập add, edit hay delete thì nó sẽ redirected về /users/login , hiển thị thông báo lỗi Missing Method in UsersController vì hiện tại ta chưa tạo action và view cho trang đăng nhập. Nên chúng ta tạo ra action login() trong /src/Controller/UsersController.php


public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error('Your username or password is incorrect.');
}
}

Và tạo file template /src/Template/Users/login.ctp


<h1>Login</h1>
<?= $this->Form->create() ?>
<?= $this->Form->control('email') ?>
<?= $this->Form->control('password') ?>
<?= $this->Form->button('Login') ?>
<?= $this->Form->end() ?>

Bây giờ bạn hãy vào danh sách bài viết bằng url: http://localhost:8888/cakephp_3_7_2/articles, rồi chọn 1 bài viết rồi tiến hành edit hay add thêm thì nó tự động chuyển đến trang login, tiến hành nhập email và password đã đổi ở trên(đã mã hoá), sau khi nhập chính xác nó sẽ tự động chuyển lại trang edit hay add mà bạn đã chọn trước đó.

Thêm phần Logout

Thêm đoạn sau vào src/Controller/UsersController.php:


public function initialize()
{
parent::initialize();
$this->Auth->allow(['logout']);
}

public function logout()
{
$this->Flash->success('You are now logged out.');
return $this->redirect($this->Auth->logout());
}

Tiến hành truy cập url: http://localhost:8888/cakephp_3_7_2/users/logout bạn sẽ nhận được thông báo ‘You are now logged out’ và quay về trang login.

Đăng ký

Nếu chưa đăng nhập mà truy cập vào http://localhost:8888/cakephp_3_7_2/users/add sẽ được chuyển đến trang login. Bây giờ chúng ta thực hiện mở trang này để người dùng có thể truy cập và đăng ký tài khoản. Trong src/Controller/UsersController.php chỉnh sửa lại dòng bên dưới, thêm action add vào:


$this->Auth->allow(['logout','add']);

Đến đây bạn có thể truy cập http://localhost:8888/cakephp_3_7_2/users/add để đăng ký user, mà không cần đăng nhập trước đó.

Giới hạn truy cập vào bài viết

Tiếp theo chúng ta sẽ làm cho user có thể chỉnh sửa bài viết của chính mình tạo ra chứ không thể chỉnh sửa bài viết của người khác. Thêm vào ArticlesController.php như sau:


public function isAuthorized($user)
{
$action = $this->request->getParam('action');
// The add and tags actions are always allowed to logged in users.
if (in_array($action, ['add', 'tags'])) {
return true;
}

// All other actions require a slug.
$slug = $this->request->getParam('pass.0');
if (!$slug) {
return false;
}

// Check that the article belongs to the current user.
$article = $this->Articles->findBySlug($slug)->first();

return $article->user_id === $user['id'];
}

Đến đây, khi truy cập vào chỉnh sửa hoặc xoá bài viết không phải của mình bạn sẽ được chuyển hướng đến trang trước đó và có thông báo.

Chỉnh sửa thêm và cập nhật bài viết

Hai action cần cập nhật là add() và edit() trong src/Controller/ArticlesController.php


public function add()
{
$article = $this->Articles->newEntity();
if ($this->request->is('post')) {
$article = $this->Articles->patchEntity($article, $this->request->getData());
// Changed: Set the user_id from the session.
$article->user_id = $this->Auth->user('id');

if ($this->Articles->save($article)) {
$this->Flash->success(__('Your article has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to add your article.'));
}
$tags = $this->Articles->Tags->find('list');

$this->set('tags', $tags);
$this->set('article', $article);
}
public function edit($slug)
{
$article = $this->Articles->findBySlug($slug)->contain('Tags')->firstOrFail();
if ($this->request->is(['post', 'put'])) {
$this->Articles->patchEntity($article, $this->request->getData(), [
// Added: Disable modification of user_id.
'accessibleFields' => ['user_id' => false]
]);
if ($this->Articles->save($article)) {
$this->Flash->success(__('Your article has been updated.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to update your article.'));
}
$tags = $this->Articles->Tags->find('list');

$this->set('tags', $tags);
$this->set('article', $article);
}

Nên nhớ rằng cần bỏ đi user_id control from ở add.ctp và edit.ctp

Đến đây thì cơ bản về một cms đơn giản đã được hoàn thành, cho phép người dùng đăng nhập, đăng bài viết, thẻ, kiểm soát giới hạn truy cập bài viết…

Kết luận

  1. Nếu có thắc mắc gì các bạn để lại comment bên dưới mình sẽ trả lời sớm nhất có thể.
  2. Cảm ơn các bạn đã đọc.

Nongdanit.info
[Cakephp 3] Bài 4 – Hướng dẫn tạo Users-Authentication