在PHPSA框架中处理用户角色(phpsa系列教程之四)
大师兄(teacherli(-at-)gmail.com) 2005-12-18
通过前三讲的内容, 大家应该可以理解PHPSA的设计思路, 这一节我们来讲一下如何来利用PHPSA提供的角色验证方式处理登录用户的角色问题.
PHPSA采用RBAC(基于角色的访问控制)方式, 将每个登录用户设定不同的角色,通过comm/config/xxx.config.xml进行定义不同角色的不同权限, 达到对系统各类资源进行细粒度的控制. 具体讲, 就是使用xxx.config.xml文件为具有不同角色的用户提供不同的module与action访问权限的限制. 简单的来说, 我们把程序按module进行划分, 然后对module按实现功能的不同划分为不同的action, 这样, 我们就可以在唯一的程序入口文件处加入对已经登录的系统用户进行权限控制, 这种控制通过Application类的private function authentication() {..}方法执行, 这个函数又通过调用Authentication类进行具体的验证, 我们所做的工作, 就是在用户登录的时候在Session类中加入用户的角色名称, 当然, 此处的角色名称要与comm/config/xxx.config.xml中的xxx一致. 默认情况即用户没有登录或是没有设定session中存放有roleName属性值时系统将使用guest.config.xml进行验证, 因此我们新加入所有用户都可以执行的module与action时, 需要将它们加入到guest.config.xml文件中.
现在来看一下我们程序中的需要: 我们要在首面加入一个用户登录与注册的窗口, 用户注册完成后的角色名为regUser, 系统管理员在验证他为合法的系统用户时会将它的角色修改为vipUser, 角色为regUser的用户可以登录系统, 登录完成后将显示"用户已经注册, 请等待网站管理人员批准, 网站管理人员将在24小时内完成用户的核实批准工作!"这样的信息; 而角色名为"vipUser"的用户登录系统后将可以显示用户信息, 修改密码, 在线学习等功能, 未经认证的用户使用?action=xxx!yyy这样的形式直接访问程序,将看到权限错误的提示信息.
用户注册部分我就不讲了, 基本与在线报名处相似, 这里以用户登录作为例子来讲一下如何在PHPSA中通过角色控制来管理登录用户.先来看一下用户数据库.
因为新加入两种角色,我们需要在comm/config/中增加regUser.config.xml与vipUser.config.xml文件, 按guest.config.xml文件的格式我们分别在这两个文件中加入对不同角色用户权限的定义.
来看user模块的loginAction中的代码:
来看workship模块的showAction:
下面总结一下使用PHPSA的角色管理的使用要点:
1. 为你的用户设定角色名称.
2. 分别以角色名称 + .config.xml文件设置角色的权限配置文件
3. 登录时在session中注册键名为roleName, 值为你设定的角色名称, 注意要与角色配置文件一致.
好, PHPSA的角色管理部分就讲到这里, 学习与使用过程中有任何问题,欢迎发邮件与我共同讨论.
大师兄(teacherli(-at-)gmail.com) 2005-12-18
通过前三讲的内容, 大家应该可以理解PHPSA的设计思路, 这一节我们来讲一下如何来利用PHPSA提供的角色验证方式处理登录用户的角色问题.
PHPSA采用RBAC(基于角色的访问控制)方式, 将每个登录用户设定不同的角色,通过comm/config/xxx.config.xml进行定义不同角色的不同权限, 达到对系统各类资源进行细粒度的控制. 具体讲, 就是使用xxx.config.xml文件为具有不同角色的用户提供不同的module与action访问权限的限制. 简单的来说, 我们把程序按module进行划分, 然后对module按实现功能的不同划分为不同的action, 这样, 我们就可以在唯一的程序入口文件处加入对已经登录的系统用户进行权限控制, 这种控制通过Application类的private function authentication() {..}方法执行, 这个函数又通过调用Authentication类进行具体的验证, 我们所做的工作, 就是在用户登录的时候在Session类中加入用户的角色名称, 当然, 此处的角色名称要与comm/config/xxx.config.xml中的xxx一致. 默认情况即用户没有登录或是没有设定session中存放有roleName属性值时系统将使用guest.config.xml进行验证, 因此我们新加入所有用户都可以执行的module与action时, 需要将它们加入到guest.config.xml文件中.
现在来看一下我们程序中的需要: 我们要在首面加入一个用户登录与注册的窗口, 用户注册完成后的角色名为regUser, 系统管理员在验证他为合法的系统用户时会将它的角色修改为vipUser, 角色为regUser的用户可以登录系统, 登录完成后将显示"用户已经注册, 请等待网站管理人员批准, 网站管理人员将在24小时内完成用户的核实批准工作!"这样的信息; 而角色名为"vipUser"的用户登录系统后将可以显示用户信息, 修改密码, 在线学习等功能, 未经认证的用户使用?action=xxx!yyy这样的形式直接访问程序,将看到权限错误的提示信息.
用户注册部分我就不讲了, 基本与在线报名处相似, 这里以用户登录作为例子来讲一下如何在PHPSA中通过角色控制来管理登录用户.先来看一下用户数据库.
CODE:
<?php
/*用户表*/
CREATE TABLE `tb_user` (
`i_id` int(10) unsigned NOT NULL auto_increment,
`vc_user_name` varchar(20) NOT NULL default '',
`vc_password` varchar(32) default NULL,
`im_role_id` int(10) unsigned default NULL,
`im_spec_id` int(10) unsigned default NULL,
`vc_real_name` varchar(20) default NULL,
`i_state_id` tinyint(4) default NULL,
PRIMARY KEY (`i_id`,`vc_user_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*用户角色表,此例中有两个角色, 1个为regUser, 另一个为vipUser*/
CREATE TABLE `tb_user_role` (
`i_id` int(10) unsigned NOT NULL auto_increment,
`vc_name` varchar(20) default NULL,
PRIMARY KEY (`i_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*记录用户登录日志*/
CREATE TABLE `tb_user_login_info` (
`vcm_user_name` varchar(20) NOT NULL default '',
`i_login_date` int(10) unsigned default NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
?>
tb_user表中im_role_id代表用户的角色号, 默认为regUser, 用户注册后则为regUser角色, 只有在网络管理员确认之后可将其角色修改为:vipUser./*用户表*/
CREATE TABLE `tb_user` (
`i_id` int(10) unsigned NOT NULL auto_increment,
`vc_user_name` varchar(20) NOT NULL default '',
`vc_password` varchar(32) default NULL,
`im_role_id` int(10) unsigned default NULL,
`im_spec_id` int(10) unsigned default NULL,
`vc_real_name` varchar(20) default NULL,
`i_state_id` tinyint(4) default NULL,
PRIMARY KEY (`i_id`,`vc_user_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*用户角色表,此例中有两个角色, 1个为regUser, 另一个为vipUser*/
CREATE TABLE `tb_user_role` (
`i_id` int(10) unsigned NOT NULL auto_increment,
`vc_name` varchar(20) default NULL,
PRIMARY KEY (`i_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*记录用户登录日志*/
CREATE TABLE `tb_user_login_info` (
`vcm_user_name` varchar(20) NOT NULL default '',
`i_login_date` int(10) unsigned default NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
?>
因为新加入两种角色,我们需要在comm/config/中增加regUser.config.xml与vipUser.config.xml文件, 按guest.config.xml文件的格式我们分别在这两个文件中加入对不同角色用户权限的定义.
来看user模块的loginAction中的代码:
CODE:
<?php
/**
* login action
*
* @author teacherlxj 2005-12-18
*/
class LoginAction extends Action {
public function LoginAction($form = null) {
parent::Action($form);
}
/**
* implements doView method
*/
public function doView() {
$this->view->setTplDir("./modules/user/views");
$this->view->setTpl("login.html");
$this->view->display();
}
/**
* implements doAction method
*/
public function doAction() {
ClassLoader::loadModelClass("user");
$userBusinessService = new UserBusinessService();
//执行逻辑验证
if (!$userBusinessService->checkLogin($this->form->getUserName(), $this->form->getPassword())) {
$actionMessage = new ActionMessage();
$actionMessage->setErrorsValue("userNamePasswordError", "用户名或是密码错误!");
return $actionMessage;
} else { //login OK
if ($userBusinessService->insertLoginLog($this->form->getUserName(), time())) {
$session = Session::getInstance();
$session->setValue("userName", $this->form->getUserName());
$userRoleName = $userBusinessService->getUserRole($this->form->getUserName());
$session->setValue("roleName", $userRoleName);
return new Forward("workship!show", "用户已经登录, 请稍后...");
}
}
}
}
?>
这里我们集中来看一下doAction函数. 第一二两句加载UserBusinessService类并实例化, 再下边的if语句为执行用户登录的逻辑验证, 这个我们上一节也讲过, 主要来看一下通过用户验证后的代码. 首先程序要插入用户登录日志, 然后获取Session类的实例, 分别设置登录用户名及登录用户角色, 注意, 这里的session->setValue("roleName", $userRoleName);必不可少, 因为Application类在执行动作的时候首先要检测Session中是否在键值为roleName的值, 不存在时使用guest.config.xml中定义的权限检测用户是否可以执行当前动作; 当roleName的值存在时将以$roleName.config.xml为权限定义文件来检测当前用户角色是否可以执行当前动作.做完此项工作后程序将重向至?action=workship!show这个地址继续执行workship模块的show动作, 至于应该给登录用户显示一个什么样的界面, 我们将在workship的showAction的doView()方法中进行判断处理./**
* login action
*
* @author teacherlxj 2005-12-18
*/
class LoginAction extends Action {
public function LoginAction($form = null) {
parent::Action($form);
}
/**
* implements doView method
*/
public function doView() {
$this->view->setTplDir("./modules/user/views");
$this->view->setTpl("login.html");
$this->view->display();
}
/**
* implements doAction method
*/
public function doAction() {
ClassLoader::loadModelClass("user");
$userBusinessService = new UserBusinessService();
//执行逻辑验证
if (!$userBusinessService->checkLogin($this->form->getUserName(), $this->form->getPassword())) {
$actionMessage = new ActionMessage();
$actionMessage->setErrorsValue("userNamePasswordError", "用户名或是密码错误!");
return $actionMessage;
} else { //login OK
if ($userBusinessService->insertLoginLog($this->form->getUserName(), time())) {
$session = Session::getInstance();
$session->setValue("userName", $this->form->getUserName());
$userRoleName = $userBusinessService->getUserRole($this->form->getUserName());
$session->setValue("roleName", $userRoleName);
return new Forward("workship!show", "用户已经登录, 请稍后...");
}
}
}
}
?>
来看workship模块的showAction:
CODE:
<?php
/**
* workship show action
* @author teacherli 2005-12-18
*/
class ShowAction extends Action {
public function ShowAction($form = null) {
parent::Action($form);
}
//show default page
public function doView() {
$this->view->setTplDir("./modules/workship/views");
$session = Session::getInstance();
$roleName = $session->getValue("roleName");
if ("regUser" == $roleName) {
$this->view->setTpl("regUser.html");
} else if("vipUser" == $roleName) {
$this->view->setTpl("vipUser.html");
} else {
$this->view->setTpl("regUser.html");
}
$this->view->display();
}
}
?>
很明显, 我们在doview()函数中使用一个条件判断语句来分别对不同的角色显示不同的界面进行处理./**
* workship show action
* @author teacherli 2005-12-18
*/
class ShowAction extends Action {
public function ShowAction($form = null) {
parent::Action($form);
}
//show default page
public function doView() {
$this->view->setTplDir("./modules/workship/views");
$session = Session::getInstance();
$roleName = $session->getValue("roleName");
if ("regUser" == $roleName) {
$this->view->setTpl("regUser.html");
} else if("vipUser" == $roleName) {
$this->view->setTpl("vipUser.html");
} else {
$this->view->setTpl("regUser.html");
}
$this->view->display();
}
}
?>
下面总结一下使用PHPSA的角色管理的使用要点:
1. 为你的用户设定角色名称.
2. 分别以角色名称 + .config.xml文件设置角色的权限配置文件
3. 登录时在session中注册键名为roleName, 值为你设定的角色名称, 注意要与角色配置文件一致.
好, PHPSA的角色管理部分就讲到这里, 学习与使用过程中有任何问题,欢迎发邮件与我共同讨论.