Cấu trúc và nội dung của một phalcon project (ver 2,08). Hướng dẫn làm project Phalcon INVO. Giải thích chi tiết về phalcon project structure
Link source code cho phalcon invo (revision 7)
Chạy project:
- Cấu hình database trong file config.php
- Run phalcon migration --action=run -> để tạo tạo lại table
- Cấu hình virtual host và chạy Website
1. Cấu trúc project (Coding trên eclipse)
├───.settings└───sample_INVO
├───.phalcon
├───app
│ ├───cache
│ ├───config
│ ├───controllers
│ ├───migrations
│ ├───models
│ └───views
│ ├───index
│ └───layouts
└───public
├───css
├───files
├───img
├───js
└───temp
2. Tạo vitual host cho project tạo vitual host
3. Routing đường dẫn
Đường dẫn của website sẽ có cấu trúc như saudomain/:Controller/:Action/:Params
- :Controller là controller hiện tại
- :Ation function tương tác với view hiện tại
- :Params là tham số người dùng gửi lên (chỉ get mới hiện tham số)
4. Cấu hình database và cấu trúc của project:
Thông thường sử dụng lệnh phalcon trên cmd đã tạo ra mặc định sẵn có chúng ta chỉ cần chỉnh sửa tham số. (Phalcon 2.08)Nội dung trong file config.php:
defined('APP_PATH') || define('APP_PATH', realpath('.'));
return new \Phalcon\Config(array(
'database' => array(
'adapter' => 'Mysql',
'host' => 'localhost',
'username' => 'root',
'password' => '',
'dbname' => 'test',
'charset' => 'utf8',
),
'application' => array(
'controllersDir' => APP_PATH . '/app/controllers/',
'modelsDir' => APP_PATH . '/app/models/',
'migrationsDir' => APP_PATH . '/app/migrations/',
'viewsDir' => APP_PATH . '/app/views/',
'pluginsDir' => APP_PATH . '/app/plugins/',
'libraryDir' => APP_PATH . '/app/library/',
'cacheDir' => APP_PATH . '/app/cache/',
'baseUri' => '/sample_INVO/',
)
));
- Đầu tiên là tham số cấu hình database là các giá trị mặc định khi tạo ra => cần sửa:
- Hệ quản trị: Mysql
- Host: localhost
- Tài khoản SQL:
- Mật khẩu SQL:
- Tên Database:
- Kiểu nhập
- Cấu hình cấu trúc phalcon project
- Thư mục chứa Controller điều khiển
- Thư mục chứa các Model tương tác với Database
- Lưu các version cập nhật của database
- Thư mục chứa view các file giao diện của website
- Thư mục chứa các plugin
- Thư mục chứa các thư viện ngoài muốn sử dụng
- Cache của website
- Thư mục mặc định root folder của project
5. Autoloaders
Autoload nằm trong /config/loader.phpChúng ta cần nạp file autoload trong /public/index.php
/**
* Read auto-loader
*/
include APP_PATH . "/app/config/loader.php";
Note: Autoloader giúp tìm kiếm và nạp và dịch các class sử dụng khi cần chứ không dịch toàn bộ
6. Đăng ký services
Service configuration nằm trong /configs/services.phpCho phép chúng ta đăng ký 1 service để sử dụng
Chúng ta cần nạp file service trong /public/index.php
/**
* Read services
*/
include APP_PATH . "/app/config/services.php";
7. Xử lý các request từ người dùng /public/index.php
/** * Handle the request */ $application = new \Phalcon\Mvc\Application($di); echo $application->handle()->getContent();
=>Tiếp nhận và xử lý các yêu cầu
8. Đăng ký session /config/services.php
Note: Cần connect được với database cấu hình trong file config.php và đăng ký tại services.php
/*** Start the session the first time some component request the session service
*/
$di->setShared('session', function () {
$session = new SessionAdapter();
$session->start();
return $session;
});
=> Đăng ký session cho lần đầu truy cập của người dùng
9. Tạo form đăng nhập start 1 session
9.1 Tạo table user trong cơ sở dữ liệu: database: invo - table: users
SQL create table:
create table users(
id int(6) primary key not null auto_increment, first_name varchar(10) not null,
last_name varchar (30) not null,
bithday date, password varchar(50) not null,
email varchar(100) not null);
9.2 Tạo form đăng nhập: Gồm email và password
Thay vì sử dụng .phtml chúng ta sử dụng .volt (volt engine)
{{ form('session/start') }} <fieldset> <div> <label for="email">Username/Email</label> <div> {{ text_field('email') }} </div> </div> <div> <label for="password">Password</label> <div> {{ password_field('password') }} </div> </div> <div> {{ submit_button('Login') }} </div> </fieldset> </form>
10. Tạo controller đăng ký session
Controller sẽ kiểm tra thông tin người dùng trong hệ thống:
- Nếu có start session và cho phép sử dụng website
- Nếu không hợp lệ thì yêu cầu đăng nhập lại
11. Tạo login vào website sử dụng phalcon ACL control
Trước khi start 1 session chúng ta cần cấu hình để kết nối tới database nếu chưa kết nối.
Nếu tạo project bằng phalcon tool thì phalcon tool sẽ tự động generate cho chúng ta.
Thư mục: /config/services.php
* Database connection is created based in the parameters defined in the configuration file */ $di->setShared('db', function () use ($config) { $dbConfig = $config->database->toArray(); $adapter = $dbConfig['adapter']; unset($dbConfig['adapter']); $class = 'Phalcon\Db\Adapter\Pdo\\' . $adapter; return new $class($dbConfig); });12. Tạo SessionController
SessionController giúp kiểm tra thông tin đăng nhập người dùng có hợp lệ hay không<?php
Note: Một số thuộc tính public cho phép truy cập trực tiếp: $this->flash, $this->request và $this->sessionclass SessionController extends ControllerBase { // ... private function _registerSession($user) { $this->session->set( 'auth', array( 'id' => $user->id, 'name' => $user->name ) ); } /** * This action authenticate and logs a user into the application */ public function startAction() { if ($this->request->isPost()) { // Get the data from the user $email = $this->request->getPost('email'); $password = $this->request->getPost('password'); // Find the user in the database $user = Users::findFirst( array( "(email = :email: OR username = :email:) AND password = :password: AND active = 'Y'", 'bind' => array( 'email' => $email, 'password' => sha1($password) ) ) ); if ($user != false) { $this->_registerSession($user); $this->flash->success('Welcome ' . $user->name); // Forward to the 'invoices' controller if the user is valid return $this->dispatcher->forward( array( 'controller' => 'invoices', 'action' => 'index' ) ); } $this->flash->error('Wrong email/password'); } // Forward to the login form again return $this->dispatcher->forward( array( 'controller' => 'session', 'action' => 'index' ) ); } }
12.1 Sau khi thực hiện kiểm tra đăng nhập hợp lệ, Controller sẽ khởi tạo 1 session có giá trị tới khi close trình duyệt
Kiểm tra yêu cầu và thông tin người dùng gửi lên bằng request
Nếu yêu cầu là post $this->request->isPost() thì lấy thông tin gửi lên (post metod là thông tin được ẩn đi)
if ($this->request->isPost()) {
$email = $this->request->getPost('email');
$password = $this->request->getPost('password');
private function _registerSession($user) { $this->session->set( 'auth', array( 'id' => $user->id, 'name' => $user->name ) ); }
Nếu người dùng không hợp lệ chuyển quay trở về đăng nhập
return $this->forward('session/index');
Kiểm tra người dùng có trong hệ thống hay không
$user = Users::findFirst( array( "(email = :email: OR username = :email:) AND password = :password: AND active = 'Y'", 'bind' => array( 'email' => $email, 'password' => sha1($password) ) ) );
Note: :email: và :password: là vị trí giá trị của người dùng nhập. Các giá trị sẽ nằm trong dấu nháy đơn
Cấu trúc trên giúp tránh SQL injection
Nếu người dùng hợp lệ thông báo và chuyển tới trang tương ứng// /config/services.php if ($user != false) { $this->_registerSession($user); $this->flash->success('Welcome ' . $user->name); return $this->forward('invoices/index'); }
13. An toàn và bảo mật trong backend
Backend là vùng giới hạn (private), chỉ những người đã đăng ký ( là thành viên mới có thể truy cập). Nếu không đăng nhập thì chỉ có thể truy cập vào những vùng public
use Phalcon\Mvc\Dispatcher; // ... /config/services.php /** * MVC dispatcher */ $di->set('dispatcher', function () { // ... $dispatcher = new Dispatcher(); return $dispatcher; });
14. Events Management
Một event cho phép chúng ta có thể thêm 1 sự kiện lắng nghe khi có 1 tác động. Ở đây là khi dispatcher xảy ra.
use Phalcon\Mvc\Dispatcher;
use Phalcon\Events\Manager as EventsManager;
$di->set('dispatcher', function () {
// Create an events manager
$eventsManager = new EventsManager();
// Listen for events produced in the dispatcher using the Security plugin
$eventsManager->attach('dispatch:beforeExecuteRoute', new SecurityPlugin);
// Handle exceptions and not-found exceptions using NotFoundPlugin
$eventsManager->attach('dispatch:beforeException', new NotFoundPlugin);
$dispatcher = new Dispatcher();
// Assign the events manager to the dispatcher
$dispatcher->setEventsManager($eventsManager);
return $dispatcher;
});
Khi 1 event gọi “beforeExecuteRoute” sẽ kích hoạt 1 plugin :
/** * Check if the user is allowed to access certain action using the SecurityPlugin */ $eventsManager->attach('dispatch:beforeExecuteRoute', new SecurityPlugin);
Xử lý khi có "beforeException" được kích hoạt
/** * Handle exceptions and not-found exceptions using NotFoundPlugin */ $eventsManager->attach('dispatch:beforeException', new NotFoundPlugin);
SercurityPlugin nằm trong /app/plugins/SercurityPlugin.php -> là 1 thủ tục trong dispatcher
Bây giờ chúng ta sẽ kiểm tra người dùng và kiểm tra quyền truy cập của người dùng xem người dùng có quyền truy cập vào vùng mà người dùng muốn hay không:use Phalcon\Events\Event; use Phalcon\Mvc\User\Plugin; use Phalcon\Mvc\Dispatcher; class SecurityPlugin extends Plugin { // ... public function beforeExecuteRoute(Event $event, Dispatcher $dispatcher) { // ... } }
use Phalcon\Acl; use Phalcon\Events\Event; use Phalcon\Mvc\User\Plugin; use Phalcon\Mvc\Dispatcher; class SecurityPlugin extends Plugin { // ... public function beforeExecuteRoute(Event $event, Dispatcher $dispatcher) { // Check whether the "auth" variable exists in session to define the active role $auth = $this->session->get('auth'); if (!$auth) { $role = 'Guests'; } else { $role = 'Users'; } // Take the active controller/action from the dispatcher $controller = $dispatcher->getControllerName(); $action = $dispatcher->getActionName(); // Obtain the ACL list $acl = $this->getAcl(); // Check if the Role have access to the controller (resource) $allowed = $acl->isAllowed($role, $controller, $action); if ($allowed != Acl::ALLOW) { // If he doesn't have access forward him to the index controller $this->flash->error("You don't have access to this module"); $dispatcher->forward( array( 'controller' => 'index', 'action' => 'index' ) ); // Returning "false" we tell to the dispatcher to stop the current operation return false; } } }
Cung cấp 1 ACL list chúng ta sử dụng $this->getAcl().
Dưới đây là các bước xây dựng 1 ACL control giới hạn người dùng
use Phalcon\Acl; use Phalcon\Acl\Role; use Phalcon\Acl\Adapter\Memory as AclList; // Create the ACL $acl = new AclList(); // The default action is DENY access $acl->setDefaultAction(Acl::DENY); // Register two roles, Users is registered users // and guests are users without a defined identity $roles = array( 'users' => new Role('Users'), 'guests' => new Role('Guests') ); foreach ($roles as $role) { $acl->addRole($role); }
-> Đã có đượng quyền cho các loại người dùng
Bây giờ chúng ta sẽ định nghĩa ra mỗi khu vực tương ứng. (public/private)
use Phalcon\Acl\Resource; // ... // Private area resources (backend) $privateResources = array( 'companies' => array('index', 'search', 'new', 'edit', 'save', 'create', 'delete'), 'products' => array('index', 'search', 'new', 'edit', 'save', 'create', 'delete'), 'producttypes' => array('index', 'search', 'new', 'edit', 'save', 'create', 'delete'), 'invoices' => array('index', 'profile') ); foreach ($privateResources as $resource => $actions) { $acl->addResource(new Resource($resource), $actions); } // Public area resources (frontend) $publicResources = array( 'index' => array('index'), 'about' => array('index'), 'register' => array('index'), 'errors' => array('show404', 'show500'), 'session' => array('index', 'register', 'start', 'end'), 'contact' => array('index', 'send') ); foreach ($publicResources as $resource => $actions) { $acl->addResource(new Resource($resource), $actions); }
Phân quyền cho từng loại người dùng với các quyền tương ứng
- Bất cứ người dùng nào cũng được vào vùng public
- Chỉ những người đăng ký mới được vào vùng private
No comments:
Post a Comment
hocphalcon.blogspot.com