Hướng dẫn học : Cakephp Authentication - Phần 2 : Viết ứng dụng đăng nhập và quản lý thành viên

Hướng dẫn học : Cakephp Authentication - Phần 2 : Viết ứng dụng đăng nhập và quản lý thành viên

Phần 2 : Viết ứng dụng đăng nhập và quản lý thành viên

1. Nội dung :
- Bài viết tập trung vào phần code và giải thích 1 số hàm quan trọng và cơ chế làm việc khi sử dụng Component Authentication.

2. Các vấn đề liên quan cần phải nắm :
- Sử dụng Form Validation
- Rút ngắn mã lệnh khi tạo form , html ... trong view

3. Viế ứng dụng cụ thể :

- Đầu tiên ta xác định mô hình làm việc của ứng dụng này . Xem tại đây

Sau khi xác định mô hình . Trong app/ tạo app_controller.php với nội dung sau :

PHP Code:

<?php
App
::import(#DD0000">'Html',#DD0000">"html");
App::import(#DD0000">'Form',#DD0000">"form");
App::import(#DD0000">'Session',#DD0000">"session");

class 
AppController extends Controller {
  
  var 
$components = array(#DD0000">'Auth');
  
  
#FF8000">/**
   * Thuc thi truoc khi goi cac controller con
   */ 
  
function beforeFilter()
  {
        
Security::setHash(#DD0000">"md5");
        
$this->Auth->userModel #DD0000">'User';
        
$this->Auth->fields = array(#DD0000">'username' => #DD0000">'username'#DD0000">'password' => #DD0000">'password');
        
$this->Auth->loginAction = array(#DD0000">'admin' => false#DD0000">'controller' => #DD0000">'users'#DD0000">'action' => #DD0000">'login');
        
$this->Auth->loginRedirect = array(#DD0000">'admin' =>true,#DD0000">'controller' => #DD0000">'users'#DD0000">'action' => #DD0000">'index');
        
$this->Auth->loginError #DD0000">'Username / password combination.  Please try again';
        
$this->Auth->authorize #DD0000">'controller';
        
        
$this->set(#DD0000">"admin",$this->_isAdmin());
        
$this->set(#DD0000">"logged_in",$this->_isLogin());
        
$this->set(#DD0000">"users_userid",$this->_usersUserID());
        
$this->set(#DD0000">"users_username",$this->_usersUsername());
  }
  
  
#FF8000">/**
   * Xac nhan co phai la admin hay khong
   * TRUE : phai
   * FASLE : khong
   */ 
  
function _isAdmin(){
    
$admin FALSE;
    if(
$this->Auth->user(#DD0000">"level")==1)
        
$admin TRUE;
    return 
$admin
  }
  
  
#FF8000">/**
   * Kiem tra da login chua
   */ 
  
function _isLogin(){
    
$login FALSE;
    if(
$this->Auth->user()){
        
$login TRUE;
    }
    return 
$login;
  }
  
  
#FF8000">/**
   * Xac nhan userID
   */ 
  
function _usersUserID(){
    
$users_userid NULL;
    if(
$this->Auth->user())
        
$users_userid $this->Auth->user(#DD0000">"id");
    return 
$users_userid;
  }
  
  
#FF8000">/**
   * Xac nhan username
   */ 
  
function _usersUsername(){
    
$users_username NULL;
    if(
$this->Auth->user())
        
$users_username $this->Auth->user(#DD0000">"username");
    return 
$users_username;
  }
  
  
#FF8000">/**
   * Xac nhan co phai truy cap vao trang admin hay khong
   */ 
  
function isAuthorized() {
        if (isset(
$this->params[#DD0000">'admin'])) {
       
            if (
$this->Auth->user(#DD0000">'level') != 1) {
                
$this->Auth->allow(#DD0000">"index");
                
$this->redirect(#DD0000">"/users");
            }
        }
        return 
true;
  }
}
?>

Ghi chú :

- Đối với các mã lệnh

PHP Code:

App::import(#DD0000">'Html',#DD0000">"html");
App::import(#DD0000">'Form',#DD0000">"form");
App::import(#DD0000">'Session',#DD0000">"session"); 



Chúng dùng để rút ngắn mã lệnh khi tạo form trong view và một mã html .. khi cần thiết.

- Để sử dụng Component Authentication ta chỉ cần khai báo :

PHP Code:

$components = array(#DD0000">'Auth'); 



- Trong đây hàm được xem là quan trọng nhất :

PHP Code:

function beforeFilter()
  {
        
Security::setHash(#DD0000">"md5");
        
$this->Auth->userModel #DD0000">'User';
        
$this->Auth->fields = array(#DD0000">'username' => #DD0000">'username'#DD0000">'password' => #DD0000">'password');
        
$this->Auth->loginAction = array(#DD0000">'admin' => false#DD0000">'controller' => #DD0000">'users'#DD0000">'action' => #DD0000">'login');
        
$this->Auth->loginRedirect = array(#DD0000">'admin' =>true,#DD0000">'controller' => #DD0000">'users'#DD0000">'action' => #DD0000">'index');
        
$this->Auth->loginError #DD0000">'Username / password combination.  Please try again';
        
$this->Auth->authorize #DD0000">'controller';
        
        
$this->set(#DD0000">"admin",$this->_isAdmin());
        
$this->set(#DD0000">"logged_in",$this->_isLogin());
        
$this->set(#DD0000">"users_userid",$this->_usersUserID());
        
$this->set(#DD0000">"users_username",$this->_usersUsername());
  } 



Hàm beforeFilter() này sẽ được gọi trước gọi function của Controller extends AppController. Đương nhiên là khi ta viết các Controller như : Users hay Products .. Phải extends AppController này rồi .

Trong này hàm :

PHP Code:

Security::setHash(#DD0000">"md5"); 



Có nghĩa là sẽ gán thuật toán mã hóa password là md5 , cái này dùng trong kiểm tra đăng nhập mật khẩu và mã hóa password khi thêm thành viên mới .
 

PHP Code:

$this->Auth->userModel #DD0000">'User';
$this->Auth->fields = array(#DD0000">'username' => #DD0000">'username'#DD0000">'password' => #DD0000">'password'); 



Sử dụng table Users với các field "username","password" để so sánh xem có hợp lệ không
 

PHP Code:

$this->Auth->loginAction = array(#DD0000">'admin' => false#DD0000">'controller' => #DD0000">'users'#DD0000">'action' => #DD0000">'login'); 



Khi không hợp lệ trang sẽ tự chuyễn tới http://localhost/thu_muc_web/users/login
 

PHP Code:

$this->Auth->loginRedirect = array(#DD0000">'admin' =>true,#DD0000">'controller' => #DD0000">'users'#DD0000">'action' => #DD0000">'index'); 



Khi hợp lệ nó sẽ tự chuyễn đến http://localhost/thu_muc_web/admin/users/index
 

PHP Code:

        $this->set(#DD0000">"admin",$this->_isAdmin());
        
$this->set(#DD0000">"logged_in",$this->_isLogin());
        
$this->set(#DD0000">"users_userid",$this->_usersUserID());
        
$this->set(#DD0000">"users_username",$this->_usersUsername()); 



Gán dữ liệu cần thiết và khi hợp lệ nó sẽ được hiển thị ở trong phần view
 

PHP Code:

function isAuthorized() {
        if (isset(
$this->params[#DD0000">'admin'])) {
       
            if (
$this->Auth->user(#DD0000">'level') != 1) {
                
$this->Auth->allow(#DD0000">"index");
                
$this->redirect(#DD0000">"/users");
            }
        }
        return 
true;
  } 



Hàm này sẽ thực khi khi đăng nhập thành công (username và password hợp lệ). Sau đó nó kiểm tra level , nếu không phải là 1 (admin) thì chuyển sang trang http://localhost/thu_muc_web/users/index và xem được các trang khác như : delete , edit, add

Vậy là chúng ta đã xong phần quan trọng nhất đó là tạo file app_controller.php

Tiếp theo tạo vào app/controllers/ tạo file users_controller.php với nội dung sau :

PHP Code:

<?php
class UsersController extends AppController{
    
    var 
$name #DD0000">"Users";
    var 
$helpers = array(#DD0000">"Html",#DD0000">"Session");
    var 
$components = array(#DD0000">"Session");
    
    function 
beforeFilter(){
        
parent::beforeFilter();
    }
    
    
    
#FF8000">/**
     * Trang chu user
     */ 
    
function index(){
       
$data $this->User->find(#DD0000">"all"); 
       
$this->set(#DD0000">"data",$data);  
    }
    
    
#FF8000">/**
     * Trang chu admin
     */ 
    
function admin_index(){
        
       
$data $this->User->find(#DD0000">"all"); 
       
$this->set(#DD0000">"data",$data);
    }
    
    
#FF8000">/**
     * Cap nhat user
     */ 
    
    
function admin_edit($id){
        if (!
$id && empty($this->data)) {
            
$this->Session->setFlash(#DD0000">'Invalid User');
            
$this->redirect(#DD0000">"/admin/users");
        }
        
        if (empty(
$this->data)) {
                
$level = array(#DD0000">"1"=>#DD0000">"administrator",#DD0000">"2"=>#DD0000">"Assistant");
                
$this->set(#DD0000">"level",$level);
                
$this->data $this->User->read(null$id);
        }else{
            
$this->User->set($this->data);
            if(
$this->User->validateUser()){
                
$this->User->save($this->data);
                
$this->Session->setFlash(#DD0000">"You has been updated user with id =".$id);
                
$this->redirect(#DD0000">"/admin/users"); 
            }
        }
    }
    
    
#FF8000">/**
     * Them moi User
     */ 
    
function admin_add() {
        if(!empty(
$this->data)){
          
          
$this->User->set($this->data);
          if(
$this->User->validateUser()){
            
$this->User->save($this->data);
            
$this->Session->setFlash(#DD0000">"You has been add new User !");
            
$this->redirect(#DD0000">"/admin/users");  
          }  
          
        }else{
          
$this->render();
          
        }
    }
    
    
#FF8000">/**
     * Xoa user
     */
    
function admin_delete($user_id){
        if(isset(
$user_id) && is_numeric($user_id)){
            
$data $this->User->read(null,$id);
            if(!empty(
$data)){
                
$this->User->delete($user_id);
                
$this->Session->setFlash(#DD0000">"Username has been deleted with id=".$user_id);
            }else{
                
$this->Session->setFlash(#DD0000">"Username is not avalible with id=".$user_id);
            }
        }else{

            
$this->Session->setFlash(#DD0000">"Username is not avalible with id=".$user_id);
        }
        
$this->redirect(#DD0000">"/admin/users");
    }
    
    
#FF8000">/**
     * Dang nhap
     */    
    
function login(){
        if (
$this->Auth->user()) {
            
$this->redirect($this->Auth->redirect());
        }
    }
    
    
#FF8000">/**
     * Dang xuat
     */ 
    
function logout(){
        
$this->redirect($this->Auth->logout());
    }
}


Trong đây cái cần chú ý nhất là :

PHP Code:

function beforeFilter(){
        
parent::beforeFilter();
    } 



Nếu không có hàm này thì không kiểm tra trước khi đăng nhập. Hàm beforeFilter() sẽ gọi ngược lên hàm beforeFilter() của class AppController và kiểm tra đăng nhập mỗi khi truy cập vào Controller User này .

Tiếp theo là tạo các file view tương ứng cho Controller User . Vào app/views/ tạo thư mục users. Sau đó lần lượt tạo các file với nội dung sau :

File admin_add.ctp :

PHP Code:

<?php echo $this->element(#DD0000">"backend/navigate");?>
<?php 
echo $session->flash(); ?>  
<?php
    
echo $form->create(#DD0000">'User'); 
    echo 
#DD0000">"<fieldset>";  
    echo 
#DD0000">"<legend>Add new User</legend>";
    
    echo 
$form->input(#DD0000">'username');
    
    echo 
$form->input(#DD0000">'pass',array(#DD0000">"type"=>#DD0000">"password"));
    
    echo 
$form->input(#DD0000">'re_pass',array(#DD0000">"type"=>#DD0000">"password"));
    
    echo 
$form->input(#DD0000">'email');
    
    
$op_gender = array(#DD0000">'1'=>#DD0000">'Male',#DD0000">'2'=>#DD0000">'Female');
    
$att = array(
        
#DD0000">"type"=>#DD0000">"radio",
        
#DD0000">"options"=>$op_gender,
        
#DD0000">"legend" => false,
        );
    echo 
$form->input(#DD0000">"gender",$att);
    
    
$options = array(#DD0000">""=>#DD0000">"Select Level",#DD0000">"1"=>#DD0000">"Administrator",#DD0000">"2"=>#DD0000">"Assistant");   
    echo 
$form->input(#DD0000">"level",array(#DD0000">"type"=>#DD0000">"select",#DD0000">"options"=>$options));
    
    echo 
$form->end(#DD0000">'Add new');
    echo 
#DD0000">"</fieldset>";
    
?>

File admin_edit.ctp

PHP Code:

<?php echo $this->element(#DD0000">"backend/navigate");?>
<?php 
echo $session->flash(); ?>  
<?php
    
echo $form->create(#DD0000">'User'); 
    echo 
#DD0000">"<fieldset>";  
    echo 
#DD0000">"<legend>Edit User</legend>";
    
    echo 
$form->input(#DD0000">'username');
    
    echo 
$form->input(#DD0000">'pass',array(#DD0000">"type"=>#DD0000">"password"));
    
    echo 
$form->input(#DD0000">'re_pass',array(#DD0000">"type"=>#DD0000">"password"));
    
    echo 
$form->input(#DD0000">'email');
    
    
$op_gender = array(#DD0000">'1'=>#DD0000">'Male',#DD0000">'2'=>#DD0000">'Female');
    
$att = array(
        
#DD0000">"type"=>#DD0000">"radio",
        
#DD0000">"options"=>$op_gender,
        
#DD0000">"legend" => false,
        );
    echo 
$form->input(#DD0000">"gender",$att);
    
    
$options = array(#DD0000">""=>#DD0000">"Select Level",#DD0000">"1"=>#DD0000">"Administrator",#DD0000">"2"=>#DD0000">"Assistant");   
    echo 
$form->input(#DD0000">"level",array(#DD0000">"type"=>#DD0000">"select",#DD0000">"options"=>$options));
    
    echo 
$form->hidden(#DD0000">"id");
    echo 
$form->end(#DD0000">'Update User');
    echo 
#DD0000">"</fieldset>";
    
?>

File admin_index.ctp

PHP Code:

<html>
<body>

<?php
#FF8000">//Load navigate
echo $this->element(#DD0000">"backend/navigate");

#FF8000">//Hien thi du lieu
if($data==NULL){
    echo 
#DD0000">"<h2>Dada Empty</h2>";
}
else{
    echo 
#DD0000">"<table>
          <tr>
            <td>User ID</td>
            <td>Username</td>
            <td>Email<td>
            <td>Level<td>
            <td><td>
          </tr>"
;
    foreach(
$data as $item){
        echo 
#DD0000">"<tr>";
        echo 
#DD0000">"<td>".$item[#DD0000">'User'][#DD0000">'id'].#DD0000">"</td>";
        echo 
#DD0000">"<td>".$item[#DD0000">'User'][#DD0000">'username'].#DD0000">"</td>";
        echo 
#DD0000">"<td>".$item[#DD0000">'User'][#DD0000">'email'].#DD0000">"</td>";
        if(
$item[#DD0000">'User'][#DD0000">'level']==1){
            
$level #DD0000">"Administrator";
        }else{
            
$level #DD0000">"Assistant";
        }
        echo 
#DD0000">"<td>".$level.#DD0000">"</td>";
        echo 
#DD0000">"<td><a href='".$this->webroot.#DD0000">"admin/users/edit/".$item[#DD0000">'User'][#DD0000">'id'].#DD0000">"' >Edit</a></td>";
        echo 
#DD0000">"<td><a href='".$this->webroot.#DD0000">"admin/users/delete/".$item[#DD0000">'User'][#DD0000">'id'].#DD0000">"' >Del</a></td>";
        echo 
#DD0000">"</tr>";
    } 
}
?>
</body>
</html>

Các bạn thấy trong các file : admin_add.ctp , admin_edit.ctp, admin_index.ctp đều có dòng lệnh để nạp thanh navigation cho admin

PHP Code:

echo $this->element(#DD0000">"backend/navigate"); 



Do đó ta vào app/views/elements/ tạo folder tên "backend" sau đó tại file navigate.ctp với nội dung sau

PHP Code:

<ul>
    <li>Login as : <?php echo $users_username;?></li>
    <li><a href='<?php echo $this->webroot.#DD0000">"admin/users";?>'>View Users</a></li>
    <li><a href='<?php echo $this->webroot.#DD0000">"admin/users/add";?>'>Add new User</a></li>
    <li><a href='<?php echo $this->webroot.#DD0000">"users/logout";?>'>Logout</a></li>
</ul>

Các file vừa tạo trên dành cho phần admin . File dưới đây là dành cho user (level=2)
File index.ctp

PHP Code:

<html>
<body>
<ul>
    <li>Login as : <?php echo $users_username;?></li>
    <li><a href='<?php echo $this->webroot.#DD0000">"users/logout";?>'>Logout</a></li>
</ul>
<?php

#FF8000">//Hien thi du lieu
if($data==NULL){
    echo 
#DD0000">"<h2>Dada Empty</h2>";
}
else{
    echo 
#DD0000">"<table>
          <tr>
            <td>User ID</td>
            <td>Username</td>
            <td>Email<td>
          </tr>"
;
    foreach(
$data as $item){
        echo 
#DD0000">"<tr>";
        echo 
#DD0000">"<td>".$item[#DD0000">'User'][#DD0000">'id'].#DD0000">"</td>";
        echo 
#DD0000">"<td>".$item[#DD0000">'User'][#DD0000">'username'].#DD0000">"</td>";
        echo 
#DD0000">"<td>".$item[#DD0000">'User'][#DD0000">'email'].#DD0000">"</td>";
        echo 
#DD0000">"</tr>";
    } 
}
?>
</body>
</html>

Và cuối cùng tạo moldel User . Ta vào app/models/ tạo file user.php với nội dung sau :

PHP Code:

<?php
class User extends AppModel{
    var 
$name #DD0000">"User";
    
    
#FF8000">//------- Valid add new User
    
function validateUser(){
        
$this->validate = array(
                                
#DD0000">"username"=>array(
                                                    
#DD0000">"rule1" =>array(
                                                                    
#DD0000">"rule" => #DD0000">"notEmpty",
                                                                    
#DD0000">"message" => #DD0000">"Username can not empty",
                                                                    ),
                                                    
#DD0000">"rule2" => array(
                                                                    
#DD0000">"rule" => #DD0000">"/^[a-z0-9_.]{4,}$/i",
                                                                    
#DD0000">"message" => #DD0000">"Username must be alpha & integer",
                                                                    ),
                                                    
#DD0000">"rule3" =>array(
                                                                    
#DD0000">"rule" => #DD0000">"checkUsername"#FF8000">// call function check Username
                                                                    
#DD0000">"message" => #DD0000">"Username has been registered",
                                                                    ),
                                                ),
                                
#DD0000">"gender" => array(
                                                    
#DD0000">"rule" => #DD0000">"notEmpty",

                                                    
#DD0000">"message" => #DD0000">"Please choise your gender",
                                                ),
                                
#DD0000">"pass"=>array(
                                                    
#DD0000">"rule" => #DD0000">"notEmpty",
                                                    
#DD0000">"message" => #DD0000">"Password can not empty",
                                                    
#DD0000">"on" => #DD0000">"create"
                                                
),
                                
#DD0000">"re_pass"=>array(
                                                    
#DD0000">"rule1"=>array(
                                                                      
#DD0000">"rule" => #DD0000">"notEmpty",
                                                                      
#DD0000">"message" => #DD0000">"Password comfirm can not empty",
                                                                      
#DD0000">"on" => #DD0000">"create"  
                                                                    
),
                                                    
#DD0000">"match" => array( 
                                                                      
#DD0000">"rule" => #DD0000">"ComparePass"#FF8000">// call function compare password
                                                                      
#DD0000">"message" => #DD0000">"Password comfirm are not match",
                                                                    ),
                                                ),
                                
#DD0000">"level"=>array(
                                                    
#DD0000">"rule" => #DD0000">"notEmpty",
                                                    
#DD0000">"message" => #DD0000">"Please select level",
                                                    
                                                ),                
                                
#DD0000">"email"=>array(
                                                    
#DD0000">"rule" => #DD0000">"email",
                                                    
#DD0000">"message" => #DD0000">"Email is not avalible",
                                                ),
                            );
        if(
$this->validates($this->validate)) 
        return 
TRUE
       else 
        return 
FALSE;
    }
    
    
#FF8000">//--------- Compare Pass
    
function ComparePass(){
        if(
$this->data[#DD0000">'User'][#DD0000">'pass']!=$this->data[#DD0000">'User'][#DD0000">'re_pass']){
            return 
FALSE;
        }
        else{
            return 
TRUE;
        }
    }
    
    
#FF8000">//-------- Check Useranme
    
function checkUsername(){
        if(isset(
$this->data[$this->name][#DD0000">'id'])){
            
$where = array(
                            
#DD0000">"id !=" => $this->data[$this->name][#DD0000">'id'],
                            
#DD0000">"username" => $this->data[$this->name][#DD0000">'username'],
                            ); 
                 
        }
        else{
            
$where = array(
                            
#DD0000">"username" => $this->data[$this->name][#DD0000">'username'],
                            );  
        } 
        
$this->find($where);
        
$count $this->getNumRows();
        if(
$count!=0){
            return 
false;
        }
        else{
            return 
true;
        }
    }
    
    
#FF8000">//--- HashPassword
    
function hashPassword($data){
        if(isset(
$this->data[#DD0000">'User'][#DD0000">'pass'])){
            
$this->data[#DD0000">'User'][#DD0000">'password'] = Security::hash($this->data[#DD0000">'User'][#DD0000">'pass'],NULL,TRUE);
            return 
$data;
        }
        return 
$data;
    }
    
#FF8000">//----- beforeSave
    
function beforeSave(){
        
$this->hashPassword(NULL,TRUE);
        return 
TRUE;
    } 
    
      
}


Trong class Model User này . Các bạn lưu ý là hàm

PHP Code:

function beforeSave(){
        
$this->hashPassword(NULL,TRUE);
        return 
TRUE;
    } 



Khi trong Controller User chạy hàm $this->User->save() thì hàm beforeSave() sẽ chạy trước khi lưu dữ liệu vào database . Mục đích của việc này mã hóa password trước khi lưu vào database . Thuật toán mã hóa sẽ là MD5 mà trong class AppController tôi đã có trình bày .

4. Chạy thử ứng dụng :

http://localhost/cakephp_auth/users/index nó sẽ chuyển sang trang đăng nhập

Khu vực của admin

Khu vực assistant

---------------

Tags: 
Bạn thấy bài viết này như thế nào?: 
No votes yet
Ảnh của Khanh Hoang

Khanh Hoang - Kenn

Kenn is a user experience designer and front end developer who enjoys creating beautiful and usable web and mobile experiences.

Advertisement

 

jobsora

Dich vu khu trung tphcm

Dich vu diet chuot tphcm

Dich vu diet con trung

Quảng Cáo Bài Viết

 
Facebook

Mỗi ngày Facebook xử lí hơn 500 TB dữ liệu

Jay Parikh, Phó Chủ tịch phụ trách cơ sở hạ tầng kĩ thuật của Facebook đã thống kê một danh sách cho thấy số dữ liệu khổng lồ mà bộ phận này này phải xử lí mỗi ngày.

Hướng dẫn chèn JS và CSS assets vào Drupal 8 theme năm 2015

Hướng dẫn chèn JS và CSS assets vào Drupal 8 theme năm 2015

In the example below global-stylingis a name of a library (a file or collection of files) that is used for global styles

Hướng dẫn xóa Drupal Field Saved vào Features

Hướng dẫn xóa Drupal Field Saved vào Features

There comes a time in every Drupal developer's day when they realize they really don't need a field on some content type or other entity. Maybe it was a field holding temporary data while you did a migration or maybe a feature

Công ty diệt chuột T&C

 

Diet con trung