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
'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
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.
"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
beginWidget("CActiveForm", array(
'id'=> get_class($model), //$_POST['ajax'] da ketadiga qiymat, va
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
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
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
beginWidget("CActiveForm", array(
'id'=> get_class($model), //$_POST['ajax'] da ketadiga qiymat, va
Yana bitta o'zgarish: protected/views/site/index.php ga qo'yidagini qo'shing
user->isGuest): ?>
Salom user->username; ?>.
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'shamiz
public 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)
Texnologiyalar
Yii da avtorizatsiya