ورود به سایت از طریق دیتابیس در Yii

تا این جای کار ما با نحوه ی ثبت , ویرایش , نمایش , حذف که به crud معروف هستن آشنا شدیم
هچنین با ویجت های فریم ورک Yii مانند cgridview , clistview , cdetailview و… آشناشدیم و کار کردیم.
توی این قسمت میخوایم نحوه ی ورود به سایت از طریق اطلاعات ذخیره شده در دیتابیسمون را آموزش بدیم.
اگه یادتون باشه با نحوه ی بازیابی الاعات در اکشن های ویو و آپدیت آشنا شدیم.


User::model()->findByPk($id);


با این کد شما با استفاده از شناسه یا همون کلید اصلی میتونین به اطلاعات یک کاربر دسترسی پیدا کنین.
حالا می خوایم با کدی آشنا بشیم که بازه ی جستجوی ما رو بیشتر کنه. یعنی بتونیم با استفاده از یه سری اطلاعات مثلا ایمیل به اطلاعات کاربر دسترسی پیدا کنیم.

خوب یه نکته: زمانی که شما میخواین وارد سایتی بشین نام کاربری و رمز عبورتون را وارد کنید.
پس از وازد کزدن اطلاعات سیستم ابتدا چک میکند که آیا همچین نام کاربری ای در دیتابیس وجود دارد یا نه . در صورتی که وجود نداشت به کاربر پیغام میده که کاربری با این مشخصات یافت نشد.
در صورتی که نام کاربری ای وجود داشت سیستم چک میکنه که آیا رمز عبور ارسالی با ایمیلی که کاربر وارد کرده تطابق داره یا نه؟
در صورتی که وجود داشت کاربر لاگین میشه و درغیر این صورت پیام میده که رمز عبور اشتباه است.

خوب
اول اینکه چطوری با استفاده از فریم ورک Yii اطلاعاتو از دیتابیس بخونیم.

User::model()->findByAttributes(array("email"=>"test@test.test","password"=>"123456"));

با استفاده از این دستور شما در جدول user کاربری با ایمیل test@test.test و رمز عبور ۱۲۳۴۵۶ را جستجو میکنین. معادل کوئریه زیر

select * from user where email="test@test.test" and password=123456

۸۰ درصد اوکی شد.
خوب اگه دقت کنین الان توی سایت ما با استفاده از نام کاربری و رمز عبور admin – admin یا demo – demo وارد سایت میشم.
بریم که داشته باشیم .
قسمت هایی که در ورود به سایت دخیل هستند عبات اند از :

  • actionLogin در کنترلر site
  • login در فولدر views فولدر site
  • loginForm در مدل ها
  • تنظیم دیتابیس در فولدر configو فایل database.php
    که ما قبلا تنظیم کردیم
  • فایل UserIdentity در فولدر components

وقتی شما آدرس صفحه ی ورود به سایت را باز میکنین

http://localhost:1007/index.php?r=site/login

کنترلر site صدازده میشه و اکشن login اجرا میشه
کد زیر actionLogin

public function actionLogin() {
$model = new LoginForm;

// if it is ajax validation request
if (isset($_POST['ajax']) && $_POST['ajax'] === 'login-form') {
echo CActiveForm::validate($model);
Yii::app()->end();
}

// collect user input data
if (isset($_POST['LoginForm'])) {
$model->attributes = $_POST['LoginForm'];
// validate user input and redirect to the previous page if valid
if ($model->validate() && $model->login())
$this->redirect(Yii::app()->user->returnUrl);
}
// display the login form
$this->render('login', array('model' => $model));
}

ابتدا مدل loginForm ایجاد شده . (مدلشم چیز خاصی نیست. چند خط بعد توضیحش میدیم). اگه درخواست ajax پست شده باشه مدل ما رو اعتبار سنجی میکنه .
فعلا راجع به این خط نمی خوایم حرف بزنیم.

خط بعدی که مهم هست . مثل actionCreate و actionUpdate هست .
اگه فورمی پستشده باشه میره مدل رو اعتبار سنجی میکنه و بعد کاربر را به صفحه ای که قرار داشته ارجا میده.(دقیقا ما جایی که این اعتبار سنجی انجام میشه را بررسی میکنیم.)
اگر پست نشده باشه میره ویوی login را نمایش میده . که در فولدر views هست.

خوب اول مدل loginForm رو ببینیم

public function actionLogin() {
$model = new LoginForm;

// if it is ajax validation request
if (isset($_POST['ajax']) && $_POST['ajax'] === 'login-form') {
echo CActiveForm::validate($model);
Yii::app()->end();
}

// collect user input data
if (isset($_POST['LoginForm'])) {
$model->attributes = $_POST['LoginForm'];
// validate user input and redirect to the previous page if valid
if ($model->validate() && $model->login())
$this->redirect(Yii::app()->user->returnUrl);
}
// display the login form
$this->render('login', array('model' => $model));
}

قسمت به قسمت این بخش رو توضیح میدیم که بخش اعتبار سنجی همین جا قرار میگیره
اول اینکه کلاسمون از CFormModel اکستند میشه .
CFormModel کلاسی هست که برای ایجاد فورم از اون استفاده میکنیم. توی تماس با ما هم از همین کلاس استفاده کردیم.:


class LoginForm extends CFormModel

بحث بعدی تعریف پروپرتی هامونه که همون متغییر هامونن

public $username;
public $password;
public $rememberMe;

private $_identity;

username و password و rememberMe که معلومه واسه چیه دیگه.
_identity در متد authenticate استفاده میشه و اطلاعات کاربری که وارد شده در اون ذخیره میشه .
متد rules که قبلا توی مدل ها توضیح داده ایم هم مشخصه که قوانینی که برای پروپرتی هامون قرار دادیم


public function rules()
{
return array(
// username and password are required
array('username, password', 'required'),
// rememberMe needs to be a boolean
array('rememberMe', 'boolean'),
// password needs to be authenticated
array('password', 'authenticate'),
);
}

خط اول که میگیم نام کاربری و رمز عبور اجباریه
خط بعدی میگیم که مرا به خاطر بیاور بولینه : true , false
و خط آخر : بحث احراز هویتون هست . که میره متد authenticateرا اجرا میکنه
.

بحث بعدیمون attributeLabels هست . که همون نام پروپرتی هامونه که در ویو نمایش داده میشه
الان username , password رو ننوشته که من اضافه کردم و حاصل شد کد زیر

public function attributeLabels() {
return array(
'rememberMe' => 'مرا به خاطر بیاور',
'username' => 'نام کاربری',
'password' => 'رمز عبور',
);
}

بحث بعدی متد login هست که بخش مهم هست

if ($this->_identity === null) {
$this->_identity = new UserIdentity($this->username, $this->password);
$this->_identity->authenticate();
}
if ($this->_identity->errorCode === UserIdentity::ERROR_NONE) {
$duration = $this->rememberMe ? 3600 * 24 * 30 : 0; // 30 days
Yii::app()->user->login($this->_identity, $duration);
return true;
} else

چون این متد قبل از authenticate اجرا میشه , ا.ل توضیح دادم.
اگه به اکشن login در کنترلر site نگاه کنین. میبینین که پس از این که اطلاعات پست شد
این کد اجرا میشه

$model->validate() && $model->login()

که validate میره rules در مدل رو چک میکنه
login میاد همین متد login در مدلمونو اجرا میکنه

خوب برگردیم روی متد لاگین
خط اول چک میکنه که _identity مقدار داره یا نه
اگه مقدار نداشت
میاد userIdentity را با استفاده از username , password ای که کاربر ارسال کرده صدا میزنه
این کجاست ؟
در فولدر components و فایل userIdentity

قسمتی که اطلاعات ارسالی کاربر باید از دیتابیس چک بشه , همین جاست ک
کدشو ببینید :

class UserIdentity extends CUserIdentity
{
/**
* Authenticates a user.
* The example implementation makes sure if the username and password
* are both 'demo'.
* In practical applications, this should be changed to authenticate
* against some persistent user identity storage (e.g. database).
* @return boolean whether authentication succeeds.
*/
public function authenticate()
{
$users=array(
// username => password
'demo'=>'demo',
'admin'=>'admin',
);
if(!isset($users[$this->username]))
$this->errorCode=self::ERROR_USERNAME_INVALID;
elseif($users[$this->username]!==$this->password)
$this->errorCode=self::ERROR_PASSWORD_INVALID;
else
$this->errorCode=self::ERROR_NONE;
return !$this->errorCode;
}
}

اگه دقت کنین الان متغییر user رو میبینین که دوتا مقدار داره
آره همینه
demo demo , admin admin
از همینجا چک میشه
$this->username یعنی نام کاربری ای که کاربر ارسال کرده
$this->password یعنی رمز عبوری که کاربر ارسال کرده


if(!isset($users[$this->username]))
$this->errorCode=self::ERROR_USERNAME_INVALID;
elseif($users[$this->username]!==$this->password)
$this->errorCode=self::ERROR_PASSWORD_INVALID;
else
$this->errorCode=self::ERROR_NONE;
return !$this->errorCode;

!isset($users[$this->username])
میگه که آیا نام کاربری ای که کاربر ارسال کرده در متغییر $users وجود نداره ؟
پس ارور بده که نام کاربری نا معتبر است

$users[$this->username]!==$this->password)
میگه اگه نام کاربری ای که ارسال شده با رمز عبور ارسال شده یکی نیست ارور بده که رمز عبور نا معتبر است
اگه هیچ کدوم نبود اروری نده

پس از این مراحل میاد بر میگرده به مدل loginModel و متد login()


$this->_identity = new UserIdentity($this->username, $this->password);
$this->_identity->authenticate();

پس از اینکه userIdentity اجرا شد مقدار ارور را بر میگردونه
میاد متد authenticate را اجرا میکنه


public function authenticate($attribute, $params) {
if (!$this->hasErrors()) {
$this->_identity = new UserIdentity($this->username, $this->password);
if (!$this->_identity->authenticate())
$this->addError('password', 'Incorrect username or password.');
}
}

این بخش هم تقریبا همون مراحل قبلو انجام میده اگه ارور داشت پیام میده .

خوب جایی که ما باید تغییر بدیم کجاست؟
همون userIdentity کافیه که یه کوئری بزنیم اطلاعات دیتابیسمونو با استفاده از پارامتر های ارسالی بخونیم اگر وجود داشت کاربر لاگین میشه و اگر نشد که وارد نمیشه

ما username , password رو از کاربر میگیریم
username همون ایمیلمونه
حالا میخوایم یه کوئری بزنیم اطلاعاتو از دیتابیس بخونیم با ایمیل و رمز عبوری که کاربر میفرسته

$user=User::model()->findByAttributes(array('email'=>$this->username,'passwod'=>$this->password))
با استفاده از اطلاعات ارسالی کاربر ما کوئری زدیم
اگر $user خالی باشه که باید پیام بدیم کاربر یافت نشد
اگر پر بود میگیم که اوکیه دیگه , لاگین شو :D

خوب من کد userIdentity رو به این شکل تغییر میدم

public function authenticate()
{
$users = User::model()->findByAttributes(array('email' => $this->username, 'password' => $this->password));

if (!isset($users))
$this->errorCode = self::ERROR_USERNAME_INVALID;
elseif ($users->password !== $this->password)
$this->errorCode = self::ERROR_PASSWORD_INVALID;
else
$this->errorCode = self::ERROR_NONE;
return !$this->errorCode;
}

فکر نمیکنم نیاز به توضیح باشه
الان شما با نام کاربری و رمز عبوری که در دیتابیس دارین میتونین وارد سایت بشین

موفق و پیروز باشین

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *