YII后台登陆可以使用YII自带的LoginForm.php用户登陆表单控件和UserIdentity.php用户验证组件。在后台中,我们可以改变这两个文件,变成MyLoginForm.php和MyUserIdentity.php,这样,可以达到与前台区分的效果,而且又不容易乱。
更改名称后,还要修改里面的代码,把里面的
class LoginForm extends CFormModel
改为:
class MyLoginForm extends CFormModel
把:
class UserIdentity extends CUserIdentity
改为:
class MyUserIdentity extends CUserIdentity
相应的,在MyLoginForm.php中的
new UserIdentity
都改为:
new MyUserIdentity
修改后,在modules/admin下新建components和models文件夹,把MyUserIdentity放到到components,把MyLoginForm放到models中。
这时候,后台就使用MyLoginForm和MyUserIdentity了。
接着在modules/admin/controllers中的WxAdminController.php下编写public function actionLogin()方法,在该方法下,new一个MyLoginForm模型
使用该模型render一个login视图。
login视图的代码如下:(该视图使用了bootstrap,所以代码跟YII有点区别)
<body>
<?php $form=$this->beginWidget('bootstrap.widgets.TbActiveForm',array(
'enableAjaxValidation'=>false,
'id'=>'horizontalForm',
'type'=>'horizontal',
));?>
<?php echo $form->errorSummary($model);?>
<?php echo $form->textFieldRow($model,'username');?>
<?php echo $form->passwordFieldRow($model,'password');?>
<div style="padding-left: 180px;">
<?php $this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'type'=>'primary', 'label'=>'登陆')); ?>
</div>
<?php $this->endWidget();?>
</body>
查看该视图生成后的HTML
<body>
<form class="form-horizontal" id="horizontalForm" action="/wxhoutai/weixin/index.php?r=admin/WxAdmin/login" method="post"> <div class="control-group "><label class="control-label required" for="MyLoginForm_username">Username <span class="required">*</span></label><div class="controls"><input name="MyLoginForm[username]" id="MyLoginForm_username" type="text" /></div></div> <div class="control-group "><label class="control-label required" for="MyLoginForm_password">Password <span class="required">*</span></label><div class="controls"><input name="MyLoginForm[password]" id="MyLoginForm_password" type="password" /></div></div> <div style="padding-left: 180px;">
<button class="btn btn-primary" type="submit" name="yt0">登陆</button>
</div>
</form></body>
可以看到,
from:
<form class="form-horizontal" id="horizontalForm" action="/wxhoutai/weixin/index.php?r=admin/WxAdmin/login" method="post">
input:
<input name="MyLoginForm[username]" id="MyLoginForm_username" type="text" />
<input name="MyLoginForm[password]" id="MyLoginForm_password" type="password" />
在表单提交上来时,会POST一个MyLoginForm的数组。
所以在actionLogin增加:
if(isset($_POST['MyLoginForm'])){
$model->attributes=$_POST['MyLoginForm'];
if($model->validate()&&$model->login()){
$_SESSION['is_admin']='yes';
$this->redirect('./index.php?r=admin/WxAdmin/admin');
}
}
表示,如果表单提交上来了,就把POST中的MyLoginForm数据都置入到$model中,这个model就是刚才在actionLogin()方法下,new出来的MyLoginForm模型
置入后,就去调用MyLoginForm的validate()方法,并且接着调用MyLoginForm的login方法。
validate()是法是MyLoginForm的父类的方法,因此MyloginForm可以直接调用。
login()方法是MyloginForm里面的方法,调用这个方法的时候,会新建一个MyUserIdentity对象,然后使用该对象去判断用户输入的用户名在数据库存不存在,存在的话,密码是否跟数据库的一样。
我们可以在MyUserIdentity.php中编写如下代码:
$user_model= WxAdmin::model()->find('username=:name',array(':name'=> $this->username));
if($user_model==NULL){
$this->errorCode= self::ERROR_USERNAME_INVALID;
return FALSE;
}elseif ($user_model->password!==$this->password) {
$this->errorCode= self::ERROR_PASSWORD_INVALID;
return FALSE;
} else {
$this->errorCode= self::ERROR_NONE;
return TRUE;
}
这代码中,首先,使用用户输入进来的username去WxAdmin中读取该用户名的数据,读出来后,保存到user_model中。
如果有数据读出来,证有有该记录,同时,该记录中也会有password属性。
接着判断$user_model->password是否等于$this->password,如果等于,证明是用户名存在和密码也正确,通过验证。
接着返回TRUE,返回到MyloginForm的Login方法,接着进行一系列的持久化操作。把用户的name保存到SESSION中。
然后之前那个IF条件成立,执行:
$_SESSION['is_admin']='yes';
$this->redirect('./index.php?r=admin/WxAdmin/admin');
这两行代码。跳到正确的页面中。
完整代码如下:
VIEW:login.php
<?php /* @var $this Controller */ ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="language" content="en" />
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->theme->baseUrl; ?>/css/styles.css" />
<title><?php echo CHtml::encode($this->pageTitle); ?></title>
<?php Yii::app()->bootstrap->register(); ?>
</head>
<body>
<?php $form=$this->beginWidget('bootstrap.widgets.TbActiveForm',array(
'enableAjaxValidation'=>false,
'id'=>'horizontalForm',
'type'=>'horizontal',
));?>
<?php echo $form->errorSummary($model);?>
<?php echo $form->textFieldRow($model,'username');?>
<?php echo $form->passwordFieldRow($model,'password');?>
<div style="padding-left: 180px;">
<?php $this->widget('bootstrap.widgets.TbButton', array('buttonType'=>'submit', 'type'=>'primary', 'label'=>'登陆')); ?>
</div>
<?php $this->endWidget();?>
</body>
</html>
WxAdminController.php
<?php
class WxAdminController extends Controller
{
/**
* @var string the default layout for the views. Defaults to '//layouts/column2', meaning
* using two-column layout. See 'protected/views/layouts/column2.php'.
*/
public $layout='//layouts/column2';
/**
* @return array action filters
*/
public function filters()
{
return array(
'accessControl', // perform access control for CRUD operations
'postOnly + delete', // we only allow deletion via POST request
);
}
/**
* Specifies the access control rules.
* This method is used by the 'accessControl' filter.
* @return array access control rules
*/
public function accessRules()
{
return array(
array('allow', // allow all users to perform 'index' and 'view' actions
'actions'=>array('index','view','login'),
'users'=>array('*'),
),
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'actions'=>array('create','update'),
'users'=>array('@'),
),
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('admin','delete'),
'users'=>array('admin'),
),
array('deny', // deny all users
'users'=>array('*'),
),
);
}
/**
* Displays a particular model.
* @param integer $id the ID of the model to be displayed
*/
public function actionView($id)
{
$this->render('view',array(
'model'=>$this->loadModel($id),
));
}
/**
* Creates a new model.
* If creation is successful, the browser will be redirected to the 'view' page.
*/
public function actionCreate()
{
$model=new WxAdmin;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['WxAdmin']))
{
$model->attributes=$_POST['WxAdmin'];
if($model->save())
Yii::app ()->user->setFlash('success','添加管理员成功');
$this->redirect(array('admin','id'=>$model->id));
}
$this->render('create',array(
'model'=>$model,
));
}
/**
* Updates a particular model.
* If update is successful, the browser will be redirected to the 'view' page.
* @param integer $id the ID of the model to be updated
*/
public function actionUpdate($id)
{
$model=$this->loadModel($id);
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['WxAdmin']))
{
$model->attributes=$_POST['WxAdmin'];
if($model->save())
Yii::app()->user->setFlash('success','修改成功');
//$this->redirect(array('view','id'=>$model->id));
$this->redirect(array('admin','id'=>$model->id));
}
$this->render('update',array(
'model'=>$model,
));
}
/**
* Deletes a particular model.
* If deletion is successful, the browser will be redirected to the 'admin' page.
* @param integer $id the ID of the model to be deleted
*/
public function actionDelete($id)
{
$this->loadModel($id)->delete();
// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
if(!isset($_GET['ajax']))
$this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));
}
/**
* Lists all models.
*/
public function actionIndex()
{
$dataProvider=new CActiveDataProvider('WxAdmin');
$this->render('index',array(
'dataProvider'=>$dataProvider,
));
}
/**
* Manages all models.
*/
public function actionAdmin()
{
$model=new WxAdmin('search');
$model->unsetAttributes(); // clear any default values
if(isset($_GET['WxAdmin']))
$model->attributes=$_GET['WxAdmin'];
$this->render('admin',array(
'model'=>$model,
));
}
public function actionLogin(){
$model=new MyLoginForm();
//当表单打开,用户输入用户名和密码后,一提交,就会POST参数进来
if(isset($_POST['MyLoginForm'])){
$model->attributes=$_POST['MyLoginForm'];
if($model->validate()&&$model->login()){
$_SESSION['is_admin']='yes';
$this->redirect('./index.php?r=admin/WxAdmin/admin');
}
}
//当login表单第一次打开是,没有POST参数,只渲染登陆表单视图。
$this->renderPartial('login',array('model'=>$model));
}
/**
* Returns the data model based on the primary key given in the GET variable.
* If the data model is not found, an HTTP exception will be raised.
* @param integer $id the ID of the model to be loaded
* @return WxAdmin the loaded model
* @throws CHttpException
*/
public function loadModel($id)
{
$model=WxAdmin::model()->findByPk($id);
if($model===null)
throw new CHttpException(404,'The requested page does not exist.');
return $model;
}
/**
* Performs the AJAX validation.
* @param WxAdmin $model the model to be validated
*/
protected function performAjaxValidation($model)
{
if(isset($_POST['ajax']) && $_POST['ajax']==='wx-admin-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
}
}
MyUserIdentity.php
<?php
/**
* UserIdentity represents the data needed to identity a user.
* It contains the authentication method that checks if the provided
* data can identity the user.
*/
class MyUserIdentity 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()
{
$user_model= WxAdmin::model()->find('username=:name',array(':name'=> $this->username));
if($user_model==NULL){
$this->errorCode= self::ERROR_USERNAME_INVALID;
return FALSE;
}elseif ($user_model->password!==$this->password) {
$this->errorCode= self::ERROR_PASSWORD_INVALID;
return FALSE;
} else {
$this->errorCode= self::ERROR_NONE;
return TRUE;
}
// $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;
}
}
MyLoginForm.php
<?php
/**
* LoginForm class.
* LoginForm is the data structure for keeping
* user login form data. It is used by the 'login' action of 'SiteController'.
*/
class MyLoginForm extends CFormModel
{
public $username;
public $password;
public $rememberMe;
private $_identity;
/**
* Declares the validation rules.
* The rules state that username and password are required,
* and password needs to be authenticated.
*/
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'),
);
}
/**
* Declares attribute labels.
*/
public function attributeLabels()
{
return array(
'rememberMe'=>'Remember me next time',
);
}
/**
* Authenticates the password.
* This is the 'authenticate' validator as declared in rules().
*/
public function authenticate($attribute,$params)
{
if(!$this->hasErrors())
{
$this->_identity=new MyUserIdentity($this->username,$this->password);
if(!$this->_identity->authenticate())
$this->addError('password','Incorrect username or password.');
}
}
/**
* Logs in the user using the given username and password in the model.
* @return boolean whether login is successful
*/
public function login()
{
if($this->_identity===null)
{
$this->_identity=new MyUserIdentity($this->username,$this->password);
$this->_identity->authenticate();
}
if($this->_identity->errorCode===MyUserIdentity::ERROR_NONE)
{
$duration=$this->rememberMe ? 3600*24*30 : 0; // 30 days
Yii::app()->user->login($this->_identity,$duration);
return true;
}
else
return false;
}
}
数据库: