Zend\Authentication là cách xác thực (ví dụ nhập user/password để kiểm tra) trong Zend Framework (Không phải là phân quyền). Ở đây nghiên cứ Authetication với ứng dụng xây dựng hệ thông đăng nhập (Login/Logout).
Zend Framework cung cấp lớp AuthenticationService
nó sử dụng các loại Adapter xác thức và bộ nhớ lưu trữ dài hạn (ví dụ Database) để tạo ra dịch vụ Xác thực.
Cài đặt vào dự án bằng lệnh composer sau:
composer require zendframework/zend-authentication
Authetication Adapter hay dùng
Khi xác thực bạn cần dùng đến một Authetication Adapter
để xác thực, trong ZF có các loại Adapter xác thực
khác nhau
(DbTable, Callback, Digest, Http, Ldap, CallbackCheckAdapter, CredentialTreatmentAdapter), chúng được mở rộng từ lớp
AbstractAdapter
nên cơ bản sử dụng chúng sẽ có dạng:
$authAdapter = /*khởi tạo theo tường loại*/ //Thiết lập Credential (pasword) và Identity (username|email|id ...) $authAdapter->setIdentity($email); $authAdapter->setCredential($password) //Thực hiện việc xác thực $result = $authAdapter->authenticate(); switch ($result->getCode()) { case Result::SUCCESS: //thành công break; default: //thất bại break; }
Kết quả của việc xác thực được lưu trong $result, từ đó xác định được xác thực thành công hay không
Result
Đối tượng Result
(Zend\Authentication\Result) là kết quả trả về từ các xác thực authenticate(). Nó có các phương thức:
getCode() | Trả về mã xác thực:
|
isValid() | Trả về true xác thực thành công |
getMessage() | Lấy thông báo về kết quả xác thực |
getIdentity() | Lấy Identity (user ...) |
CredentialTreatmentAdapter
CredentialTreatmentAdapter
là loại Adapter xác thực mà nó thi hành một câu lệnh SQL
để truy cấn bẳng dữ liệu dựa trên identity, credential cung cấp. Nếu SQL có trả về identity thì xác thực thành công.
Thường sử dụng MD5()
hoặc PASSWORD()
để chuyển đổi credential
Giả sử bạn có bảng tên user
, trong bảng có cột username
và password
.
Giờ bạn muốn tạo CredentialTreatmentAdapter xác thực bằng dữ liệu: username, password
, có mấy trường hợp sau:
(1) Cột password không mã hóa gì
$authAdapter = new \Zend\Authentication\Adapter\DbTable\CredentialTreatmentAdapter( $dbAdapter, //Zend\Db\Adapter\Adapter 'users', //Tên bảng 'username', //Tên cột tương ứng với identity 'password' //Tên cột tương ứng với credential '?' //Password không mã hóa ); //Xác thực $authAdapter->setIdentity('usernameabc'); $authAdapter->setCredential('passwordabc') //Thực hiện việc xác thực $result = $authAdapter->authenticate();
(2) Cột password mã hóa một lần MD5 hoặc PASSWORD
$authAdapter = new \Zend\Authentication\Adapter\DbTable\CredentialTreatmentAdapter( $dbAdapter, //Zend\Db\Adapter\Adapter 'users', //Tên bảng 'username', //Tên cột tương ứng với identity 'password' //Tên cột tương ứng với credential 'MD5(?)' //Hoặc PASSWORD(?) );
CredentialTreatmentAdapter bản chất khi hoạt động nó tạo ra câu lệnh SQL, với ký hiểu ?
đại diện cho dữ credential truyền vào bạn
có thể tùy biến câu lệnh SQL phức tạp tùy ý
Ví dụ bảng user
có thêm cột active
bạn chỉ cho phép xác thực các user ở trạng thái active = true
$authAdapter = new \Zend\Authentication\Adapter\DbTable\CredentialTreatmentAdapter( $dbAdapter, //Zend\Db\Adapter\Adapter 'users', //Tên bảng 'username', //Tên cột tương ứng với identity 'password' //Tên cột tương ứng với credential 'MD5(?) AND active = "TRUE"' );
(3) Các tùy biến phức tạp
Bạn có thể lấy chính đối tượng Select
để thiết lập: (xem Where)
$authAdapter = new \Zend\Authentication\Adapter\DbTable\CredentialTreatmentAdapter(
$dbAdapter,
'users',
'username',
'password'
'MD5(?)'
);
$select = $authAdapter->getDbSelect();
$select->where('active = "TRUE"');
Hoặc password có sử dụng đến salt (xem thêm Salt),
với chuỗi salt lưu tại cột password_salt
$authAdapter = new \Zend\Authentication\Adapter\DbTable\CredentialTreatmentAdapter( $dbAdapter, 'users', 'username', 'password' 'MD5(CONCAT(?, password_salt))' );
CallbackCheck
Adapter xác thực CallbackCheck
cũng tạo câu lệnh SQL truy vấn đến CSDL như CredentialTreatmentAdapter
,
tuy nhiên nó lại dùng một hàm Callback để kiểm tra credential
Hàm callback phải có dạng:
//Trả về true thành công, false thất bại //$hash là giá trị credential $authAdapter truyền vào lấy từ DB //$password là giá trị đưa vào kiểm tra $passwordValidation = function ($hash, $password) { //...code kiểm tra theo cách của bạn return $result; };
Ví dụ: sử dụng hàm callback với Password có sử dụng Bcrypt
$passwordValidation = function($dbCredential, $requestCredential) { $bcrypt =new \Zend\Crypt\Password\Bcrypt(); $bcrypt->setCost(14); return $bcrypt->verify($requestCredential,$dbCredential); };
Tạo ra một Adapter: CallbackCheck
như sau
$authAdapter = new AuthAdapter( $dbAdapter, 'users', 'username', 'password', $passwordValidation );
Hoặc
$authAdapter = new AuthAdapter( $dbAdapter, 'users', 'username', 'password', function ($hash, $password) { //...code kiểm tra theo cách của bạn return $result; } );
AuthenticationService
Khi sử dụng Adapter xác thực như trên thì sau khi xác thực thành công phải có cơ chế lưu trữ lại để trong cùng phiên truy cập không cần đăng nhập mỗi khi có Request mới gửi đến. Lức này bạn cần dùng tới AuthenticationService
AuthenticationService
nó chứa bên trong một Adapter xác thực, một bộ lưu trữ dữ liệu cố định
(ta sử dụng Zend\Authentication\Storage\Session
để dùng $_SESSION
lưu trữ thông tin đăng nhập)
Ví dụ tạo ra một AuthenticationService $auth:
//$authAdapter đã có, tạo theo cách ở phần trên //Tạo lưu trữ bằng Session $storageSession = new Zend\Authentication\Storage\Session('XTLAB') $auth = new AuthenticationService($storageSession,$authAdapter);
Các phương thức của AuthenticationService
getAdapter() | Lấy đối tượng Adapter xác thực |
getStorage() | Lấy Storage, nơi lưu để nhớ thông tin xác thực |
hasIdentity() | Kiểm tra có tồn tại Indentity (lưu thông tin xác thực) |
getIdentity() | Lấy Indentity (lưu thông tin xác thực) |
clearIdentity() | Xóa thông tin đăng nhập |
authenticate() | Tiến hành xác thực, trả về Result.
$auth->getStorage()->clear(); $auth ->getAdapter() ->setIdentity($Identity) ->setCredential($Credential); $result = $auth->authenticate(); |
Đăng ký AuthenticationService là dịch vụ hệ thống
Nếu bạn đăng ký vào Service Manager của hệ thống một AuthenticationService, với key là : Zend\Authentication\AuthenticationService
thì bạn đã có một dịch vụ xác thực mặc định.
Thường thiết lập trong config
//... 'service_manager' => [ 'factories' => [ \Zend\Authentication\AuthenticationService::class => 'factory_create_AuthenticationService' ] //... ],
Nếu có đăng ký dịch vụ trên thì Plugin Controller Identity()
và View Helper Identity()
sẽ hoạt động, như vậy trong View, Controller bạn sẽ
dễ dàng lấy được thông tin người dùng đăng nhập (hoặc không có đăng nhập thì Identity() trả về null)