Yii da avtorizatsiya
Salom. Ushbu maqola buyurtmaga asosan yozildi. So'ralgan narsa juda ham aktual mavzulardan biridir. Ya'ni Yii da foydalanuvchilar bilan ishlash. Agar CMS larni qarasangiz deyarli hammasida foydalanuvchilar bilan ishlash bir xil texnologiya bilan amalga oshirilgan. Umuman foydalanuvchilar bilan ishlashda siz PHP SESSION ni bilishingiz kerak bo'ladi.
Yii da session bilan ishlagan bo'lsangiz bu juda yaxshi, agar ishlamagan bo'lsangiz man yo'l yo'lakay tushingirishga harakat qilaman.
Ishni boshlashdan oldin bitta site.me nomli host yaratamiz (Denwer, XAMPP,… da). Keyin unga Yii framework papkasini ko'chiramiz. WebAPP ni o'rnatmaymiz, hammasini o'zimiz yozamiz. Avvalo maqolada ko'rsatilgan index.php, protected/config/main.php, protected/controllers/SiteController.php, protected/views/site/index.php larni yarating. Keyin protected/config/main.php dagi
larni o'zgartirib, site.me ga kirsangiz
natija chiqishi kerak. Agar chiqqan bo'lsa demak hammasi OK. Davom etamiz.
CUserIdentity — bu komponent tizimga kirayotgan foydalanuvchi login/parollar mosligini tekshiraid.
CWebUser — bu tizimga kirgan foydalanuvchi haqida ma'lumot saqlaydi.
CDbAuthManager, CPhpAuthManager — bu tizimga kirgan foydalanuvchi huquqlarini saqlaydi. Ya'ni admin yoki oddiy foydalanuvchi yoki menedjerligini. CDbAuthManager — bu ma'lumotlarni bazada saqlaydi, CPhpAuthManager — bu php faylda saqlaydi.
CAccessControlFilter — bu tizimga kirgan foydalanuvchi huquqidan kelib kelib chiqib ayrim funksiyalarda ruxsat berish yoki bermaslikni hal qiladi.
CDbHttpSession, CHttpSession — PHP sessiya, birinchisi bazada saqlaydi, ikkinchisi faylda.
CActiveRecord — bu bazadagi jadvallar bilan ishlashni osonlashtiradigan class.
Qisqacha shular, bulardan tashqari ya'na bir qancha komponentlardan foydalanamiz.
Agar jadvallarni yaratgan bo'lsangiz endi shu jadvallar bilan ishlaydigan CActiveRecord dan nasl olingan modellarni yaratamiz. Buning uchun protected papkasi ichiga models papkasini yarating va models ning ichiga:
UsersModel.php
fayllarini yarating. Va protected/config/main.php dagi «components» ga MB bilan bog'lanish ma'lumotlarni yozing.
Bu sozlashlar mani kompimga moslangan, sizda boshqacharoq bo'lishi mumkin.
Va endi UsersModel.php ga qo'yidagilarni qo'shamiz.
va oxirgisi, protected/views/users/register.php faylini yaratamiz va ichiga
ni yozamiz va site.me/index.php?r=users/register ga kirsak ro'yxatdan o'tish formasi chiqadi. Shundan ro'yxatdan o'tib MB (ma'lumotlar bazasi) ni ko'rsangiz siz kiritgan ma'lumotlar yozilgan bo'lishi kerak. Agar yozilgan bo'lsa hammasi OK. Endi login formasini yasaymiz.
UsersController.php ga quyidagini qo'shamiz
UsersModel.php ga quyidagilarni qo'shamiz
va quyidagicha o'zgartirish kiritamiz. rules metodidagi:
e'tibor bergan bo'lsangiz «on» => «register» ning o'rniga «on» => «register login» qo'shdik. Bu degani ushbu tekshirish ro'yxatdan o'tish formasi va tizimga kirish formari uchun o'rinlidir deganidir. Bu bitta tekshirishni ikki marta yozmaslikni oldini oladi.
Endi yangi 2 ta fayl yaratamiz. protected papkasi ichiga components papkasini yaratmiz va shu papka ichiga
UserIdentity.php faylini yaratamiz. Kod
WebUser fayli. Kod
protected/config/main.php ga WebUser haqida ko'rsatamiz
Ko'pchilik Yii haqidagi kitoblarda WebUser da setState funksiyasini ishlatgan. Buni funksiya user haqidagi ma'lumotlarni sessiyada saqlaydi. Siz bu usulni ishlatsangiz, man tepada yozgan kod umuman boshqacha bo'ladi. Mani holatimda har safar MB dan foydalanuvchi haqida ma'lumot olinadi.
Va oxirgisi: protected/views/users/login.php fayli. Kod
Yana bitta o'zgarish: protected/views/site/index.php ga qo'yidagini qo'shing
Agar login bo'lgan bo'lsangiz, «Salom shranet. Tizimdan chiqish» ko'rinishida xabar chiqish kerak.
Shuning bilan ro'yxatdan o'tish, tizimga kirish va tizimdan chiqishlar haqida mana yozib bo'ldik. Ochig'i rollar haqida ham yozmoqchi edim, lekin maqolam yana 2 baravarga ko'payadi deb o'ylab keyingi maqolaga qoldirdim.
Agar savollar bo'lsa marhamat.
Source kodni ko'chirish (frameworksiz)
Yii da session bilan ishlagan bo'lsangiz bu juda yaxshi, agar ishlamagan bo'lsangiz man yo'l yo'lakay tushingirishga harakat qilaman.
Ishni boshlashdan oldin bitta site.me nomli host yaratamiz (Denwer, XAMPP,… da). Keyin unga Yii framework papkasini ko'chiramiz. WebAPP ni o'rnatmaymiz, hammasini o'zimiz yozamiz. Avvalo maqolada ko'rsatilgan index.php, protected/config/main.php, protected/controllers/SiteController.php, protected/views/site/index.php larni yarating. Keyin protected/config/main.php dagi
'name'=>'Yii avtorizatsiya',
'defaultController' => 'site',
larni o'zgartirib, site.me ga kirsangiz
Salom Yii. Man index.php view (ko'rinish) fayliman. Mening manzilim: {protected.views.site.index.php turgan manzil}
natija chiqishi kerak. Agar chiqqan bo'lsa demak hammasi OK. Davom etamiz.
Ishlatiladigan komponentlar haqida
Yii da avtorizatsiyali sayt yasash uchun o'zining maxsus komponentlari mavjud, bular:CUserIdentity — bu komponent tizimga kirayotgan foydalanuvchi login/parollar mosligini tekshiraid.
CWebUser — bu tizimga kirgan foydalanuvchi haqida ma'lumot saqlaydi.
CDbAuthManager, CPhpAuthManager — bu tizimga kirgan foydalanuvchi huquqlarini saqlaydi. Ya'ni admin yoki oddiy foydalanuvchi yoki menedjerligini. CDbAuthManager — bu ma'lumotlarni bazada saqlaydi, CPhpAuthManager — bu php faylda saqlaydi.
CAccessControlFilter — bu tizimga kirgan foydalanuvchi huquqidan kelib kelib chiqib ayrim funksiyalarda ruxsat berish yoki bermaslikni hal qiladi.
CDbHttpSession, CHttpSession — PHP sessiya, birinchisi bazada saqlaydi, ikkinchisi faylda.
CActiveRecord — bu bazadagi jadvallar bilan ishlashni osonlashtiradigan class.
Qisqacha shular, bulardan tashqari ya'na bir qancha komponentlardan foydalanamiz.
Ma'lumotlar bazasi
«site» nomli bitta baza yaratamiz va unga quyidagi jadvallarni yaratamiz.-- Foydalanuvchilar ro'yxati
CREATE TABLE IF NOT EXISTS `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(20) NOT NULL,
`password` varchar(32) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Agar jadvallarni yaratgan bo'lsangiz endi shu jadvallar bilan ishlaydigan CActiveRecord dan nasl olingan modellarni yaratamiz. Buning uchun protected papkasi ichiga models papkasini yarating va models ning ichiga:
UsersModel.php
<?php
class UsersModel extends CActiveRecord
{
//Ro'yxatdan o'tishda parollar mosligini tekshirish uchun kerak
public $confirm;
//UsersModel obyektini yaratish umuman new UsersModel() ning analogi
public static function model($className = __CLASS__)
{
return CActiveRecord::model($className);
}
//Ma'lumotlar bazasidagi jadval nomi
public function tableName()
{
return 'users';
}
//Shu jadvaldagi PRIMARY column nomi
public function primaryKey()
{
return 'id';
}
}
fayllarini yarating. Va protected/config/main.php dagi «components» ga MB bilan bog'lanish ma'lumotlarni yozing.
"components" => array(
...
'db' => array(
'connectionString' => 'mysql:host=192.168.56.101;dbname=site',
'emulatePrepare' => true,
'username' => 'root',
'password' => '1',
'charset' => 'utf8'
)
...
)
Bu sozlashlar mani kompimga moslangan, sizda boshqacharoq bo'lishi mumkin.
Registratsiya
Foydalanuvchi tizimga kirishidan oldin ro'yxatdan o'tishi kerak, shuning uchun ishni shundan boshlaymiz. Buning uchun bizga UsersController.php kerak bo'ladi. Buni protected/controllers ga yaratmiz va ichiga quyidagini yozamiz.<?php
class UsersController extends CController
{
public function actionRegister()
{
/**
* UsersModel dan obyekt olamiz
* Bu obyekt orqali foydalanuvchi ro'yxatdan
* o'tish jarayonidagi xatoliklarni tekshiramiz
* "register" - bu scenari nomi, buni UsersModel
* classi ichida ishlatamiz rules metodi ichida
* "on" => "register" ko'rinishida ishlatiladi
*/
$model = new UsersModel("register");
$className = get_class($model);
/**
* Formani AJAX texnologiyasi yordamida tekshirish
*/
if (strcmp(Yii::app()->request->getParam("ajax"), $className) === 0)
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
/**
* Kelayotgan forma ma'lumotlari borligini tekshirish
*/
if (isset($_POST[$className]) && is_array($_POST[$className]))
{
/**
* Agar $_POST da ma'lumot bo'lsa uni $model ga yuklaymiz
* va kiritilgan ma'lumotlarni tekshiramiz ($model->validate()
*/
$model->attributes = $_POST[$className];
if ($model->validate())
{
/**
* Kiritilgan ma'lumotlar to'g'ri bo'lsa
* ularni bazaga kiritamiz
*/
$model->insert();
/**
* Login formasiga o'tkazish
*/
$this->redirect(array("login"));
}
}
$this->render("register", array(
"model" => $model
));
}
}
Va endi UsersModel.php ga qo'yidagilarni qo'shamiz.
...
/**
* Maydon nomlari
*/
public function attributeLabels()
{
return array(
'username' => "Foydalanuvchi nomi",
"password" => "Parol",
'confirm' => "Parol takroran"
);
}
/**
* Foydalanuvchi ma'lumotlarini tekshirish
*/
public function rules()
{
return array(
//RO'YXATDAN O'TISH FORMASINI TEKSHIRISH
//maydonlar kiritilishi majburiy
array('username, password, confirm', 'required', 'on' => "register"),
//foydalanuvchi nomi uzunligini tekshirish, kamida 3 ta belgi, ko'pi bilan 20 ta belgi
array('username', 'length', 'min' => 3, 'max' => 20),
//foydalanuvchi nomi belgilarini tekshirish, faqat lotin harflari bo'lishi shart degan shartni berish (REGEX).
array('username', 'match', 'pattern' => '/^[a-z]+$/i', "on" => "register"),
//foydalanuvchi nomi borligini tekshirish
array('username', 'usernameExistsInTheTable', "on" => "register"),
//parollar uzunligi teksirish, kamida 6 ta belgi
array('password, confirm', 'length', 'min' => 6, "on" => "register"),
//parollar bir biriga to'g'ri kelishini tekshirish
array('confirm', 'compare', 'compareAttribute' => 'password')
);
}
public function usernameExistsInTheTable($attribute, $params)
{
//agar $attribute maydonida xatolik bo'lsa tekshirmaymiz
if ($this->hasErrors($attribute))
return;
/**
* $this->{$attribute} bu foydalanuvchi ro'yxatdan
* o'tish formasida username maydoniga kiritgan
* qiymatni beradi. Shu qiymat bo'yicha jadvalni
* tekshiramiz
*/
$exist = UsersModel::model()->exists("username = :username", array(
":username" => $this->{$attribute}
));
/**
* Agar username mavjud bo'lsa, uni borligi
* haqida foydalanuvchi xabar beramiz
*/
if ($exist)
$this->addError($attribute, "Siz kiritgan username mavjud");
}
va oxirgisi, protected/views/users/register.php faylini yaratamiz va ichiga
<?php $form = $this->beginWidget("CActiveForm", array(
'id'=> get_class($model), //$_POST['ajax'] da ketadiga qiymat, va <form id="{qiymat}" ... >
'enableAjaxValidation'=>true, //AJAX texnologiyasi orqali formani validatsiya qilish
'clientOptions'=>array(
'validateOnSubmit'=>true, //formani SUBMIT tugmasini bosgan paytda ham tekshirish
))); ?>
<table border='0'>
<tr>
<td><?php
//UsersModel::attributeLabels dagi mos qiymatni olish
echo $form->labelEx($model, 'username');
?></td>
<td>
<?php
//<input type="text" ... /> elementi
echo $form->textField($model, 'username');
?>
<?php
//xatoliklarni chiqruvchi <div>...</div>
echo $form->error($model, 'username');
?>
</td>
</tr>
<tr>
<td><?php echo $form->labelEx($model, 'password'); ?></td>
<td>
<?php echo $form->passwordField($model, 'password'); ?>
<?php echo $form->error($model, 'password'); ?>
</td>
</tr>
<tr>
<td><?php echo $form->labelEx($model, 'confirm'); ?></td>
<td>
<?php echo $form->passwordField($model, 'confirm'); ?>
<?php echo $form->error($model, 'confirm'); ?>
</td>
</tr>
</table>
<button type="submit">Ro'yxatdan o'tish</button>
<?php $this->endWidget();
ni yozamiz va site.me/index.php?r=users/register ga kirsak ro'yxatdan o'tish formasi chiqadi. Shundan ro'yxatdan o'tib MB (ma'lumotlar bazasi) ni ko'rsangiz siz kiritgan ma'lumotlar yozilgan bo'lishi kerak. Agar yozilgan bo'lsa hammasi OK. Endi login formasini yasaymiz.
Tizimga kirish
Tizimga kirish jarayonini yaratish uchun quyidagi o'zgarishlarni kiritamiz:UsersController.php ga quyidagini qo'shamiz
public function actionLogin()
{
$model = new UsersModel("login");
$className = get_class($model);
if (strcmp(Yii::app()->request->getParam("ajax"), $className) === 0)
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
if (isset($_POST[$className]) && is_array($_POST[$className]))
{
$model->attributes = $_POST[$className];
//validatsiya qilish va login qilish
if ($model->validate() && $model->login())
{
//agar validatsiyadan o'tib va login ham bo'lsa
$this->redirect(array("site/index"));
}
}
$this->render("login", array(
"model" => $model
));
}
UsersModel.php ga quyidagilarni qo'shamiz
private $_identity;
public function auth($attribute, $params)
{
if ($this->hasErrors($attribute))
return;
if ($this->_identity === null)
$this->_identity = new UserIdentity($this->username, $this->password);
if ( ! $this->_identity->authenticate())
$this->addError($attribute, "Login yoki parol noto'g'ri");
}
public function login()
{
if ($this->_identity === null)
$this->_identity = new UserIdentity($this->username, $this->password);
if ($this->_identity->authenticate())
{
Yii::app()->user->login($this->_identity);
return true;
}
return false;
}
va quyidagicha o'zgartirish kiritamiz. rules metodidagi:
//array('username', 'length', 'min' => 3, 'max' => 20, 'on' => 'register'),
//array('username', 'match', 'pattern' => '/^[a-z]+$/i', "on" => "register"),
array('username', 'length', 'min' => 3, 'max' => 20, 'on' => 'register login'),
array('username', 'match', 'pattern' => '/^[a-z]+$/i', "on" => "register login"),
e'tibor bergan bo'lsangiz «on» => «register» ning o'rniga «on» => «register login» qo'shdik. Bu degani ushbu tekshirish ro'yxatdan o'tish formasi va tizimga kirish formari uchun o'rinlidir deganidir. Bu bitta tekshirishni ikki marta yozmaslikni oldini oladi.
Endi yangi 2 ta fayl yaratamiz. protected papkasi ichiga components papkasini yaratmiz va shu papka ichiga
UserIdentity.php faylini yaratamiz. Kod
<?php
class UserIdentity extends CUserIdentity
{
public $_id;
public function authenticate()
{
/**
* Userni username qiymati orqali qidirish
*/
$user = UsersModel::model()->findByAttributes(array(
"username" => $this->username
));
//agar foydalanuvchi mavjud bo'lmasa
if ( ! $user)
return false;
//foydalanuvchi mavjud bo'lsa va parollar mos kelsa
if (strcmp($user->password, $this->password) !== 0)
return false;
//user ID sini saqlash
$this->_id = $user->id;
return true;
}
/**
* Bu metod, CWebUser da chaqiriladi
* var CWebUser::$id ga o'zlashtiriladi
*/
public function getId()
{
return $this->_id;
}
}
WebUser fayli. Kod
<?php
class WebUser extends CWebUser
{
public $userData;
public function init()
{
//CWebUser::init ni chaqirish
parent::init();
/**
* Agar mehmon bo'lmasa
* Ya'ni tizimga kirgan bo'lsa
*/
if ( ! $this->isGuest)
{
/**
* UserIdentity da getId ga tizimga kirgan
* foydalanuvchi id sini bergan edi. Shu qiymatni
* CWebUser orqali $this->getId ko'rinishida olinadi.
*
* Bu iddan kelib chiqib biz tizimga kirgan foydalanuvchi
* kimligini aniqlaymiz
*/
$user = UsersModel::model()->findByPk($this->getId());
/**
* Agar ID mavjud bo'lmasa
*
* Bu tekshirish nima uchun kerak?
* Agar {ID} li foydalanuvchi tizimga kirgan bo'lsa
* va shu vaqtda admin tomonidan o'sha foydalanuvchi
* o'chirilsa. Demak u foydalanuvchi tizimdan chiqishi kerak
*/
if ( ! $user)
$this->logout(); //tizimdan chiqish
else
{
/**
* User haqidagi ma'lumotlarni saqlaymiz
*/
$this->userData = $user;
}
}
}
/**
* $this->userData dan qiymatni olish
* Agar siz Yii::app()->user->username deb
* yozsangiz, ushbu funksiya chaqiriladi
* bundan siz userData dan qiymatni qaytarasiz
*/
public function __get($name)
{
if (isset($this->userData->{$name}))
return $this->userData->{$name};
return parent::__get($name);
}
}
protected/config/main.php ga WebUser haqida ko'rsatamiz
"components" => array(
...
'user' => array(
'class' => 'WebUser'
),
...
)
Ko'pchilik Yii haqidagi kitoblarda WebUser da setState funksiyasini ishlatgan. Buni funksiya user haqidagi ma'lumotlarni sessiyada saqlaydi. Siz bu usulni ishlatsangiz, man tepada yozgan kod umuman boshqacha bo'ladi. Mani holatimda har safar MB dan foydalanuvchi haqida ma'lumot olinadi.
Va oxirgisi: protected/views/users/login.php fayli. Kod
<?php $form = $this->beginWidget("CActiveForm", array(
'id'=> get_class($model), //$_POST['ajax'] da ketadiga qiymat, va <form id="{qiymat}" ... >
'enableAjaxValidation'=>true, //AJAX texnologiyasi orqali formani validatsiya qilish
'clientOptions'=>array(
'validateOnSubmit'=>true, //formani SUBMIT tugmasini bosgan paytda ham tekshirish
))); ?>
<table border='0'>
<tr>
<td><?php
//UsersModel::attributeValues dagi mos qiymatni olish
echo $form->labelEx($model, 'username');
?></td>
<td>
<?php
//<input type="text" ... /> elementi
echo $form->textField($model, 'username');
?>
<?php
//xatoliklarni chiqruvchi <div>...</div>
echo $form->error($model, 'username');
?>
</td>
</tr>
<tr>
<td><?php echo $form->labelEx($model, 'password'); ?></td>
<td>
<?php echo $form->passwordField($model, 'password'); ?>
<?php echo $form->error($model, 'password'); ?>
</td>
</tr>
</table>
<button type="submit">Tizimga kirish</button>
<?php $this->endWidget();
Yana bitta o'zgarish: protected/views/site/index.php ga qo'yidagini qo'shing
<?php if ( ! Yii::app()->user->isGuest): ?>
Salom <?php echo Yii::app()->user->username; ?>.
<?php echo CHtml::link("Tizimdan chiqish", array("users/logout")); ?>
<?php else: ?>
<?php echo CHtml::link("Kirish", array("users/login")); ?>
<?php endif; ?>
Agar login bo'lgan bo'lsangiz, «Salom shranet. Tizimdan chiqish» ko'rinishida xabar chiqish kerak.
Tizimdan chiqish
Ochig'i bundan oson narsa yo'q. Buning uchun UsersController.php da quyidagini qo'shamizpublic function actionLogout()
{
Yii::app()->user->logout();
$this->redirect(array("site/index"));
}
Shuning bilan ro'yxatdan o'tish, tizimga kirish va tizimdan chiqishlar haqida mana yozib bo'ldik. Ochig'i rollar haqida ham yozmoqchi edim, lekin maqolam yana 2 baravarga ko'payadi deb o'ylab keyingi maqolaga qoldirdim.
Ha ya'na ko'p izohlar kodda komentariya ko'rinishida keltirilgan. Koddagi izohlarni o'qing.
Agar savollar bo'lsa marhamat.
Source kodni ko'chirish (frameworksiz)
1 комментарий