最近在做一个网站类型的项目,要对用户的访问模块(权限)进行控制,所以设计并实现了一套简单的权限控制功能。
用户:users
模块:modules
SQL代码:
/*
Target Server Type : MYSQL
Target Server Version : 50628
File Encoding : 65001
Date: 2016-08-26 10:35:28
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `modules`
-- ----------------------------
DROP TABLE IF EXISTS `modules`;
CREATE TABLE `modules` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`module` varchar(30) DEFAULT NULL COMMENT '模块',
`pid` int(10) DEFAULT NULL COMMENT '上一级id',
`level` int(4) DEFAULT NULL COMMENT '级别',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of modules
-- ----------------------------
-- ----------------------------
-- Table structure for `users`
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`user_code` varchar(10) NOT NULL COMMENT '用户代码',
`user_name` varchar(40) DEFAULT NULL COMMENT '用户名',
`user_password` varchar(100) DEFAULT NULL COMMENT '密码',
`qq` varchar(15) DEFAULT NULL COMMENT 'qq',
`msn` varchar(50) DEFAULT NULL COMMENT 'msn',
`demo` varchar(100) DEFAULT NULL COMMENT '备注',
`auth_code` text COMMENT '权限码',
PRIMARY KEY (`user_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of users
-- ----------------------------
项目中用SSM+freemarker框架,把权限封装成权限树的数据结构,然后转成json格式。
<#include "common/res.html" />
展示效果如下:
在控制层把数据转成json格式,发到展示层。
/**
* @fun 获取分店用户权限
* @author 皮锋
* @date 2016/8/25
* @param session
* @param id
* @param substoreid
* @return
*/
@RequestMapping("getUserRightMaskById")
@ResponseBody
public Object getUserRightMaskById(HttpSession session,String id,String substoreid){
substoreid=StringUtils.isEmpty(substoreid)?String.valueOf(session.getAttribute("substoreid")):substoreid;
//判断是酒店还是客栈
List
/**
* @fun 获取分店用户权限
* @author 皮锋
* @date 2016/8/25
* @param substoreid
* @param id
* @param versions
* @return Map
*/
@Override
public Map getUserRightMaskOnTree(String substoreid, String id, String versions) {
Map userRightMask=this.iRightMaskDao.getUserRightMaskBySubAndId(substoreid,id);
List
a.在数据层按权限级别从modules表中分别拿出不同级别的权限
select id,module,pid,level from modules where level='0'
select id,module,pid,level from modules where level='1'
select id,module,pid,level from modules where level='2'
b.在users表中拿出某用户的所有权限(权限码)
select auth_code from users where user_code='pifeng'
c.保存权限时不同级别之间的权限码用英式分号“;”隔开,同一级别之间的权限码用英式逗号“,”隔开。例如:1,2,3,4,5,6,7,8,9,10,11,12;13,14,15,16,17,18,19,20,21,22,23,24,25,26,36,37,27,28,29,30,31,32,33,34,35,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,56,57,58,59,60,61,62,63,64,133,65,66,67,68,69,70,71,72,73,74,75,126,127,128,129,130,131,76,77,78,79,80,81,82,83,84,85,86,87,88,99,124,134,135,136,140,141,89,90,91,92,93,94,95,96,97,98,137,138,139,100,101,102,103,106,107,132,108,109,110,111,112,113,114,115,116,125,117,118,119,120,121,122
a.freemarker在xml文件中的配置
/WEB-INF/ftl/
auto_detect
0
UTF-8
UTF-8
zh_CN
yyyy-MM-dd
HH:mm:ss
0.######
yyyy-MM-dd HH:mm:ss
true
inc/spring.ftl as base
b.写个类继承TemplateMethodModel类,实现freemarker自定义方法,用于实现控制页面模块是否显示
登陆的时候把用户权限码存入session中,然后从session中取权限。下面是一个例子:
public class MenuFunction implements TemplateMethodModel{
@Override
public Object exec(List arg0) throws TemplateModelException {
int level = Integer.valueOf(arg0.get(0).toString()); //模块等级
int modelId=Integer.valueOf(arg0.get(1).toString()); //模块id
int count=0; //记录session是否有此模块的权限码
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpSession session=request.getSession();
Object o = session.getAttribute("info");
if(o==null)
return false;
Info info = (Info) o;
String authCode=info.getUser().getAuthCode(); //权限码
if(authCode.contains(";")){
String[] masks=authCode.split(";");
String[] m=masks[level].split(",");
for (int i = 0; i < m.length; i++) {
if(modelId==Integer.parseInt(m[i])){
++count;
}else{
count+=0;
}
}
}
if(count==0){
return false;
}else{
return true;
}
}
}
c.在页面使用freemarker标签,控制模块的显示隐藏
Menucall中的两个参数,第一个为模块等级,第二个为模块的id
例如:
<#if menucall(1,122)>
预订
#if>
以上就是对用户的访问模块(权限)进行控制的大体实现。