YII学习,实现基于数据库的后台登录,用户体系.
上次研究Yii框架写到了要完成用户登陆系统.这次接着上次的写.
参考官方权威指南和参考手册,外加各种博客文章.历尽千辛万苦,数遍天上滴星星.完成了后台用户登录.这里用到了YII框架的
CUserIdentity类. -------实现基于用户名和密码的验证.
CWebForm类 ---------登录表单
CController类 ------控制器的基础类
CWebUser类 ------储存用户的持久身份信息
第一步:分离用户系统
要想实现用户登录.先研究一下YII的登录流程.YII框架提供和很有用的登录辅助类和用户身份类供我们使用.上次说到admin使用模块来开发管理后台.那么要实现后台与前台的相对独立.首先要实现前后台两套用户系统.YII的CUserIdentity类是用来提供用户身份相关的存储,验证等操作.这个类在默认的配置文件main.php里面有配置.就是配置文件里面components下面的user.查看手册可以看到这几行配置就是配置的CUserIdentity的一个实例.以后可以通过Yii::app()->user来访问这个实例.调用其中的方法.但是我想要两套用户系统.一套用作网站的前台登录.一套用作管理的后台登录.那么就要修改这个配置.用户系统是基于CUserIdentity类.那么如果我想要两套用户系统,就要有两个CUserIdentity的实例.也可以有两个CUserIdentity的子类.这样也能够实现用户系统的分离.我把其中用作前台登录的类叫做WebUsers类.这个类放在网站根目录下的components下面放置一个Webusers.php文件.里面只写明class WebUsers extends CWebUser{}就可以了.当我以后想修改网站用户的一些基础属性.只需要修改这个类就成了.另外一个类我放在admin模块下的components下面.同上面的一样只写明class AdminUsers extends CWebUser{}就可以了.在最后我在main里面配置一下.
修改原来user的声明改成以下的样子
'components'=>array(
'user'=>array(
'class'=>'WebUsers',
'stateKeyPrefix'=>'user',//设置前台session前缀
'allowAutoLogin'=>true,
),
'admin'=>array(
// enable cookie-based authentication
'class'=>'AdminUsers',
'stateKeyPrefix'=>'admin',//设置后台session前缀
'allowAutoLogin'=>false,
'loginUrl' =>array('/admin/adminuser/login'),
),
之前上文说过.这个配置数组是用来配置类的.也就是说我分别对前台和后台的两个用于保存网站用户的实例进行了配置.经过这样的配置.我就能够通过Yii::app()->user访问到网站用户的相关属性和调用相关的方法.而通过Yii::app()->admin来访问网站后台管理用户的相关属性,并调用相关的方法.
第二步:完成控制器.
分离完了用户系统.就要写控制器了.因为CMS系统需要验证用户身份.也就是说没有正确的账号密码是不允许进行任何操作的.换个逻辑讲就是说在模块下的控制器的任何方法都应该在权限验证通过的情况下才能被执行.为了能够实现这个目的.我写了一个后台控制器的基础类,所有用作后台操作的控制器都继承自此控制器.这个控制器的名称我给定义成了AdminController.它继承自Ccontroller.我把这个类的文件存储在components下面,这样就会被模块的init方法自动导入进来.我可以通过手册发现在Ccontroller里面有一个方法叫做beforeAction().我只需要重写这个方法.在所有action执行之前验证用户身份.如果用户身份不合法.就直接引导到登录页面上去.这个是我们的实现思想.
小插曲:验证码.
想做登录,那么验证码这个关键的东西是不能够少的.在YII的框架中有提供验证码.但是使用起来比较让人费解.它说要实现验证码.我们需要重写控制器中的actions方法.完成一个继承自CCaptchaAction的action并且要求这个继承来的方法名字必须是captcha.这里我没有深入的研究,参考yii框架自动生成的联系页面上验证码的生成.我写了验证码.当然.验证码可以进行配置.只需要配置数组即可.
完成上述步骤后.我的后台管理用到的基础控制器就完成了.代码是下面这个样子的:
class AdminController extends CController
{
public $pageTitle="后台管理";
/**
* @var string the default layout for the controller view. Defaults to '//layouts/column1',
* meaning using a single column layout. See 'protected/views/layouts/column1.php'.
*/
public $layout='application.modules.admin.views.layouts.admin';
/**
* @var array context menu items. This property will be assigned to {@link CMenu::items}.
*/
public $menu=array();
/**
* @var array the breadcrumbs of the current page. The value of this property will
* be assigned to {@link CBreadcrumbs::links}. Please refer to {@link CBreadcrumbs::links}
* for more details on how to specify this property.
*/
public $breadcrumbs=array();
public function actions(){
return array(
'captcha'=>array(
'class'=>'CCaptchaAction',
'backColor'=>0xFFFFFF,
),);
}
protected function beforeAction($action){
if(Yii::app()->admin->isGuest&&$action->getId()!='login'&&$action->getId()!='captcha'){
$this->redirect(Yii::app()->admin->loginUrl);
}
return parent::beforeAction($action);
}
}
说一下这个beforeAction 第一行.我们判断我们之前声明的后台用户体系中的当前用户是不是来宾用户.并且判断当前的Action是不是为login或者captcha,也就是当前是不是在登录或者生成验证码.因为对于没有登录的用户,如果不允许登录操作和生成验证码操作就没办法完成登录. 第二行.如果条件成立.也就是说当前的用户没有登录.那么我们就调用控制器里面的重定向方法,将访问定向到我们之前再用户体系中声明的loginUrl去.最后一行.如果我们的用户登录了.那么我们就调用父类的这个方法.实际上父类的方法里面是直接去执行action了.
好了,我的基础控制器完成了,在这里我们定义了验证码,控制了用户登录.接下来我就要写后台用户的第一个控制器了,用户控制器.里面要实现的方法大概有(还没想好),用户登录,用户基本信息获取.用户登出.显示登录后台的首页.再想到再添加.于是完成了第一个控制器.AdminUserController,具体代码如下:
class AdminuserController extends AdminController
{
public function actionIndex()
{
$this->render('index');
}
public function actionLogin()
{
$model=new AdminLoginForm;
if(isset($_POST['AdminLoginForm']))
{
$model->attributes=$_POST['AdminLoginForm'];//将用户输入块赋值给AdminLoginForm的实例
if($r = $model->validate())
{
// form inputs are valid, do something here
$this->actionIndex();//若登陆成功则显示首页
//$this->renderPartial('login',array('model'=>$model));
return;
}
}
$this->renderPartial('login',array('model'=>$model));
}
public function actionLogout(){
Yii::app()->admin->logout();
$this->actionLogin();
}
}
代码贴出来了,先别着急看.这里面的actionLogin先不用去理解.我定义了三个动作.分别是login,logout,index,还有一个从父类继承过来的captcha.分别用来登录,登出,显示首页和显示验证码.
第三步,建立模型.
yii有很好的抽象结构.将数据抽象成两种模式,一种是用作表单的,这样的数据不被持久化保存.于是有表单模型.另外一种是用来抽象数据库的模型.这种数据会被保存到数据库里面.第二种模型里面封装了数据库的增删改查的方法.官方叫做CActiveRecord,我们可以理解为第二种模型为数据模型.第一种模型为表单模型.
表单模型,故名思议就是对表单的一个抽象.这个模型里面定义了表单的各个属性和字段.定义了表单的验证规则.等等.当渲染一个表单的时候实际上是生成了一个表单模型的实例.当我们填写一个表单并提交的时候实际上完成的操作应该是把用户输入的数据用来填充这个模型.并保证用户填充的数据能够满足这里的验证规则.也就是说我们对表单的操作实际上就是对这个表单模型实例的操作.按照Yii框架的设计原则,我们的表单模型都应该集成自表单模型的基类.而数据模型都应该集成自数据模型的基类.这两个基类分别是 CFormModel,CActiveRecord.
拿我们的登录表单来说.我们的登录表单继承自CFormModel,里面有几个属性.分别是用户名.密码.验证码.有一个方法,这个方法通过提交表单来收集用户输入并用已经定义的规则来比对用户输入.如果满足,就将用户输入赋值给表单模型实例的相应属性上,如果不满足就写入错误信息.(这个方法的名字叫做validate,是从CFormModel继承过来的//是用来验证的.)
数据模型.对应数据表的模型.可以理解为我们把数据库里面某一张表抽象为一个模型.这个表里面的每一行就是这个模型的一个实例.当我们执行这个数据模型的增删改查操作的时候,实际上就是对这个表的操作.而转换成面向对象的思想.我们就是在操作着数据对象.还拿我们的后台管理用户系统来说.我们需要实现对于后台用户表的抽象.于是我们有了一个后台用户表的数据模型类.继承自CActiveRecord.(可以用GII生成).我是用Gii生成的.
我的登陆表单模型如下:
<?php /**
* ContactForm class.
* ContactForm is the data structure for keeping
* contact form data. It is used by the 'contact' action of 'SiteController'.
*/
class AdminLoginForm extends CFormModel
{
public $username;
public $password;
public $verifyCode;//验证码
private $_adminUserIdentity;//这个变量实际上是基于用户名和密码验证的类的实例 /**
* Declares the validation rules.
*/
public function rules()
{
return array(
array('verifyCode', 'captcha', 'allowEmpty'=>!CCaptcha::checkRequirements()),
//当没有开启GD库拓展的时候允许验证码为空
array('username, password','required'),
//用户名密码不能为空
// verifyCode needs to be entered correctly
array('password', 'check_user'),//定义password需要使用该模型中的check_user方法来验证.
);
}
public function attributeLabels()
{
return array(
'username'=>'用户名',
'password'=>'密码',
'verifyCode'=>'验证码',
);
}
public function check_user($attribute,$params)
{
$this->_adminUserIdentity = new AdminUserIdentity($this->username,$this->password);
$res = $this->_adminUserIdentity->authenticate();
//调用authenticate方法来验证用户提交的信息与数据库里面存储的信息是否一致.
if($res == true){
Yii::app()->admin->login($this->_adminUserIdentity);
return true;
}else{
return false;
}
}
}
第四步,理清逻辑.
先看看我们手里有什么,
有AdminuserController控制器.
有在main.php里面声明的admin用户体系,实际上是CWebUser的一个实例.
基于用户密码来验证的AdminUserIdentity.
有loginform的表单模型.(可以用gii来建立)
有admin_user数据表的数据模型.(可以用gii来建立)
当然,我们还要有一张存储用户数据的数据表.这个要自己在数据库里面建立了.这个就不写出来了.
我们需要一个能够渲染管理后台首页的视图.可能还要写一些layout.
还少什么:
少一个登录界面的视图.
那就来建立一个登录界面的视图.在yii权威指南里面可以找到使用表单那个章节.里面介绍了表单助手类的使用.这里我就不再说了.想要在前端展示验证码.可以参考例子程序.实际上<?php $this->widget('CCaptcha'); ?>就能够完成验证码的图片输出.this指的是控制器的实例,而widget值得是渲染一个挂件.当传递进入的参数为CCaptcha时就能够直接生成一个验证码.
上面提到的还有我的后台管理用户的用户体系文件,放上来如下:
<?php
class AdminUserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$record = AdminUser::model()->findByAttributes(array('username'=>$this->username));
if($record===null)
{
$this->errorMessage = '用户名不存在';
$this->errorCode=true;
}
else if($record->password!==md5($this->password))
{
$this->errorMessage = '密码不正确';
$this->errorCode=true;
} else
{
$this->_id=$record->id;
$this->setState('title', $record->username);
$this->errorCode=false;
}
return !$this->errorCode;
} public function getId()
{
return $this->_id;
}
}
到现在已经准备的差不多了,简单画了一下登录的流程.如下:

写到这里,就完成了基本的登录流程.当有用户来访问的时候我们就可以实现必须强制登录.其实我上面所说的东西,在官方的文档上也有很多描述,可以多啃啃手册.
上次我做了一个类比,把YII比作一个汽车工厂.这次.我们可以把后台这个模块比作一个大的生产车间.那么我们在main里面声明的AdminUsers类的实例就相当于一个管理这个生产车间的管理员,负责监管人员进入生产车间和离开生产车间,而AdminUserIdentity 这个基于用户名密码的验证类就相当于一个基于用户名密码的开门器.如果你没有相应的用户名密码.也不能够进入车间进行工作.
就写到这里.接下来要实现后台用户的管理.增删改查功能.如果你耐心的看完了这篇博文并觉得有收货的话,请帮忙赞一下.
YII学习,实现基于数据库的后台登录,用户体系.的更多相关文章
- MySQL 查询 存储过程 视图 触发器 函数 索引 建表语句 数据库版本 当前登录用户 当前数据库名称
MySQL 查询 存储过程 视图 触发器 函数 索引 建表语句 数据库版本 当前登录用户 当前数据库名称 INFORMATION_SCHEMA.TABLES INFORMATION_SCHEMA. ...
- 接单,开发,学习神器--基于SpringSecurity的后台权限管理系统
基于SpringSecurity--码仔后台管理系统 1.技术选项 >- 核心框架 SpringBoot >- 权限框架 SpringSecurity >- 模板引擎 Thymele ...
- SpringSecurity学习之基于数据库的用户认证
SpringSecurity给我们提供了一套最基本的认证方式,可是这种方式远远不能满足大多数系统的需求.不过好在SpringSecurity给我们预留了许多可扩展的接口给我们,我们可以基于这些接口实现 ...
- 微信网页开发之获取用户unionID的两种方法--基于微信的多点登录用户识别
假设网站A有以下功能需求:1,pc端微信扫码登录:2,微信浏览器中的静默登录功能需求,这两种需求就需要用到用户的unionID,这样才能在多个登录点(终端)识别用户.那么这两种需求下用户的unionI ...
- CAS学习笔记二:CAS单点登录流程
背景 由于公司项目甲方众多,各甲方为了统一登录用户体系实现单点登录(SSO)开始要求各乙方项目对接其搭建的CAS单点登录服务,有段时间对CAS的流程很迷,各厂商还有基于CAS进行二次开发的情况,所以对 ...
- Yii创建前台和后台登录表单和通过扩展 CWebUser 增加信息到 Yii::app()->user
我参考了这篇文章来构建项目的前台和后台的目录结构.感谢Andy的这篇文章.按照所有的步骤,您将有单独的前台和后台面板,如: http://localhost/index.php // 前台 http: ...
- 爬虫学习之基于Scrapy的爬虫自动登录
###概述 在前面两篇(爬虫学习之基于Scrapy的网络爬虫和爬虫学习之简单的网络爬虫)文章中我们通过两个实际的案例,采用不同的方式进行了内容提取.我们对网络爬虫有了一个比较初级的认识,只要发起请求获 ...
- [python][django学习篇][11]后台admin用户登录博客,添加文章---这一章和博客首页设计没有关系
1 如果没有创建超级管理员账号,先要创建python manage.py createsuperuser 2 在admin后台注册模型(如果没有这一步,登录http://127.0.0.1:8000/ ...
- SQLSever--基础学习--创建登录用户&创建数据库用户&分配权限
如题,本文简记一下SQL Sever里面登录用户(login)的创建,数据库用户(DBUser)的创建,以及给数据库用户分配权限(Grant). 数据库有三层保护机制: 第一层:登录用户以及登录密码的 ...
随机推荐
- Lucene学习总结之五:Lucene段合并(merge)过程分析
一.段合并过程总论 IndexWriter中与段合并有关的成员变量有: HashSet<SegmentInfo> mergingSegments = new HashSet<Segm ...
- CSS3弹性盒模型布局模块介绍
来源:Robert’s talk原文:http://robertnyman.com/2010/12/02/css3-flexible-box-layout-module-aka-flex-box-in ...
- 清空DNS缓存
昨天写了个Python的脚本,功能就是爬取一个网页上的Google ip地址再写入到本机的hosts里面去. 但是写完并且运行完成之后发现上不了Google.于是想到了是不是要清空一下DNS的缓存.不 ...
- postgresql配置的一些问题
ubuntu通过软件中心安装后,配置文件位于如下目录 我用超级用户创建了其它数据库用户,发现是登录不了的,必须还得创建同名的linux用户,甚是麻烦.在配置文件pg_hba.conf中发现了问题. 其 ...
- Jmeter的简单练习
一.安装Jmeter 1.下载Jmeter 下载地址:http://jmeter.apache.org/download_jmeter.cgi 目前最新版为2.9,其余文件如源代码等也可从如下官网下载 ...
- 用lsb_release -a 查看linux版本
1.要通过yum 安装上这个命令的软件包 yum -y install redhat-lsb 2.lsb_release -a 查看linux版本信息
- html模块一些方法
<pre name="code" class="python"> find_by_tag_name: @elements = $h->find ...
- ##解决 ViewPager 调用 notifyDataSetChanged()无刷新:原理、解决办法##
一.原理 转自:http://www.cnblogs.com/maoyu417/p/3740209.html 转载 http://www.67tgb.com/?p=624 最近项目结束,搞了一次代码分 ...
- Raphaël—JavaScript Library
Raphaël-JavaScript Library What is it? Raphaël is a small JavaScript library that should simplify yo ...
- canvas.js | CLiPS
canvas.js | CLiPS canvas.js The canvas.js module is a simple and robust JavaScript API for the HTML5 ...