javaWeb用户权限控制简单实现

xiaoxiao2021-02-28  74

1. 数据库设计

用户:users

模块:modules

SQL代码:

[sql]  view plain  copy /*   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',     `levelint(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   -- ----------------------------  

1. 后端实现

项目中用SSM+freemarker框架,把权限封装成权限树的数据结构,然后转成json格式。

1) 展示层采用ztree树(setUserauthOnTree.html

[html]  view plain  copy <!DOCTYPE html>   <html>   <head>   <#include "common/res.html" />   <script src="${base.ctx}/js/layer-v2.1/laypage/laypage.js"></script>   <link href="${base.ctx}/js/layer-v2.1/laypage/skin/laypage.css" rel="stylesheet" type="text/css"/>   <script src="${base.ctx}/js/layer-v2.1/layer/layer.js"></script>   <!-- 引入树形菜单样式 -->   <link href="${base.ctx}/component/ztree/css/zTreeStyle/zTreeStyle.css" rel="stylesheet" type="text/css" />   <script type="text/javascript" src="${base.ctx}/component/ztree/js/jquery.ztree.core-3.5.js"></script>   <script type="text/javascript" src="${base.ctx}/component/ztree/js/jquery.ztree.excheck-3.5.js"></script>   <style type="text/css">   .blue-madison {       border: 1px solid #7ca7cc;       border-top: 0;   }      .caption {       background-color: #578ebe;       border-bottom: 0;       padding: 0 10px;       margin-bottom: 0;       color: #fff;   }   </style>   </head>   <body>       <div class="portlet-body"  style="overflow-y:auto; width:400px; height:550px;">       <div id="ztree" >           <ul id="treeDemo" class="ztree"></ul>       </div>       </div>       <div class="form-actions">           <div class="row">               <div class="col-sm-12" align="center" style="margin-top: 5px">                   <button type='button' class="btn btn-primary"                       onclick="editModle()">确定</button>                   <button type="button" class="btn btn-primary" id="cancel">关闭</button>               </div>           </div>       </div>       <script>           $("document").ready(function() {               $.ajax({                       type : "post",                       url : "${base.ctx}/Setup/getUserRightMaskById",                       data:{"id":"${userId}"},                       dataType : "json",                       success : function(result) {                           zTreeObj = $.fn.zTree.init($("#treeDemo"), setting,result.datas.data);                           zTreeObj.expandAll(true);                       },                       error : function() {                          }                   });           });              //加载树           var zTreeObj;           // zTree 的参数配置,深入使用请参考 API 文档(setting 配置详解)           var setting = {               view : {                   //dblClickExpand : false,                   showLine : true,                  //是否显示节点间的连线                 },               check: {                       enable: true,                       //nocheckInherit: false,                       chkStyle: "checkbox",                       chkboxType: { "Y": "ps", "N": "ps" },                       //autoCheckTrigger: true               },               callback : {                   onCheck: zTreeOnCheck,               }           };                      //checkbox点击的回调事件           function zTreeOnCheck(event, treeId, treeNode) {                 /* var zTree = $.fn.zTree.getZTreeObj("treeDemo");                 var changedNodes = zTree.getChangeCheckedNodes();                 for ( var i=0 ; i < changedNodes.length ; i++ ){                     var treeNode = changedNodes[i];                 }   */             };                        function editModle(){               var rootId=null;               var midId=null;               var minId=null;               var treeObj = $.fn.zTree.getZTreeObj("treeDemo");               var nodes = treeObj.getCheckedNodes();                              for(var i=0;i<nodes.length;i++){                   if(nodes[i].level==0){                       rootId=rootId+","+nodes[i].id;                   }                   if(nodes[i].level==1){                       midId=midId+","+nodes[i].id;                   }                   if(nodes[i].level==2){                       minId=minId+","+nodes[i].id;                   }               }               if(rootId!=null){                   rootId=rootId.substring(5,rootId.length);               }               if(midId!=null){                   midId=midId.substring(5,midId.length);               }               if(minId!=null){                   minId=minId.substring(5,minId.length);               }               $.ajax({                       type : "post",                       url : "${base.ctx}/Setup/updateUserRightMaskByAjax",                       dataType : "json",                       data:{"rootId":rootId,"midId":midId,"minId":minId,"userId":"${userId}"},                       success : function(result) {                           if(result=="1"){                               layer.msg("赋权成功!");                               setTimeout(function(){top.dialog.get("set-dialog").close().remove();} , 600);                           }                       },                       error : function() {                           layer.msg("系统错误,请联系管理员!");                       }                   });           }                      //关闭           $("#cancel").click(function() {               top.dialog.get("set-dialog").close().remove();           });       </script>   </body>   </html>  

展示效果如下:

2) controller控制层用springmvc

在控制层把数据转成json格式,发到展示层。

[java]  view plain  copy /**       * @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<Map<String, Object>> versionsList=this.setupService.getHotelHotelVersions(substoreid);           Object versions=versionsList.get(0).get("versions");           Map<String, Object> hotelMap=new HashMap<String, Object>();           if((null!=versionsList)&&(versionsList.size()!=0)){  //list不为空               if("complete".equals(versions)){   //酒店                   //查询酒店权限树                   hotelMap=this.rightMaskService.getUserRightMaskOnTree(substoreid,id,"complete");               }else if("simple".equals(versions)){  //客栈                   //查询客栈权限树                   hotelMap=this.rightMaskService.getUserRightMaskOnTree(substoreid,id,"simple");               }           }           Map<String, Object> resultMap = new HashMap<String, Object>();           resultMap.put("datas", hotelMap);                      return JSONObject.toJSONString(resultMap, SerializerFeature.WriteMapNullValue);       }  

3)service服务层把权限封装成满足ztree格式的树数据结构

[java]  view plain  copy /**       * @fun 获取分店用户权限       * @author 皮锋       * @date 2016/8/25       * @param substoreid       * @param id       * @param versions       * @return Map<String, Object>       */       @Override       public Map<String, Object> getUserRightMaskOnTree(String substoreid, String id, String versions) {           Map<String, Object> userRightMask=this.iRightMaskDao.getUserRightMaskBySubAndId(substoreid,id);           List<Map<String, Object>> listOne = new ArrayList<Map<String,Object>>();           List<Map<String, Object>> listTwo = new ArrayList<Map<String,Object>>();           //List<Map<String, Object>> listThree = new ArrayList<Map<String,Object>>();           List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();           if(versions.equals("complete")){  //酒店               listOne = this.iRightMaskDao.getRightMaskOnHotelOne();               listTwo = this.iRightMaskDao.getRightMaskOnHotelTwo();               //listThree = this.iRightMaskDao.getRightMaskOnHotelThree();               packagingToTwoTree(resultList,listOne,listTwo,userRightMask);           }else if(versions.equals("simple")){  //客栈               listOne = this.iRightMaskDao.getRightMaskOnTavernOne();               listTwo = this.iRightMaskDao.getRightMaskOnTavernTwo();               //listThree = this.iRightMaskDao.getRightMaskOnTavernThree();               packagingToTwoTree(resultList,listOne,listTwo,userRightMask);           }           Map<String, Object> map = new HashMap<String, Object>();           map.put("data", resultList);           return map;       }   /**       * @function 封装一个一级树       * @author 皮锋       * @date 2016/8/26       * @param resultList       * @param listOne       * @param authCode       * @return void       */       private void packagingToOneTree(List<Map<String, Object>> resultList,               List<Map<String, Object>> listOne, Map<String, Object> authCode) {           for (int i = 0; i < listOne.size(); i++) {               Map<String, Object> rootMap = new HashMap<String, Object>();               rootMap.put("id", listOne.get(i).get("id"));               rootMap.put("name", listOne.get(i).get("module"));               if (validateRightMask(listOne, authCode, i) != -1) {                   rootMap.put("checked"true);               } else {                   rootMap.put("checked"false);               }               resultList.add(rootMap);           }       }          /**       * @function 封装一个二级树       * @author 皮锋       * @date 2016/8/26       * @param resultList       * @param listOne       * @param listTwo       * @param authCode       * @return void       */       private void packagingToTwoTree(List<Map<String, Object>> resultList,               List<Map<String, Object>> listOne,               List<Map<String, Object>> listTwo, Map<String, Object> authCode) {           for (int i = 0; i < listOne.size(); i++) {                  List<Map<String, Object>> midList = new ArrayList<Map<String, Object>>();               for (int j = 0; j < listTwo.size(); j++) {                      if (listTwo.get(j).get("pid").toString()                           .equals(listOne.get(i).get("id").toString())) {                          List<Map<String, Object>> minlist = new ArrayList<Map<String, Object>>();                          Map<String, Object> midMap = new HashMap<String, Object>();                       midMap.put("id", listTwo.get(j).get("id"));                       midMap.put("name", listTwo.get(j).get("module"));                       midMap.put("children", minlist);                       if (validateRightMask(listTwo, authCode, j) != -1) {                           midMap.put("checked"true);                       } else {                           midMap.put("checked"false);                       }                       midList.add(midMap);                   }               }               Map<String, Object> rootMap = new HashMap<String, Object>();               rootMap.put("id", listOne.get(i).get("id"));               rootMap.put("name", listOne.get(i).get("module"));               rootMap.put("children", midList);               if (validateRightMask(listOne, authCode, i) != -1) {                   rootMap.put("checked"true);               } else {                   rootMap.put("checked"false);               }               resultList.add(rootMap);           }       }          /**       * @function 封装一个三级树       * @author 皮锋       * @date 2016/8/26       * @param resultList       * @param listOne       * @param listTwo       * @param listThree       * @param authCode       * @return void       */       private void packagingToThreeTree(List<Map<String, Object>> resultList,               List<Map<String, Object>> listOne,               List<Map<String, Object>> listTwo,               List<Map<String, Object>> listThree, Map<String, Object> authCode) {           for (int i = 0; i < listOne.size(); i++) {                  List<Map<String, Object>> midList = new ArrayList<Map<String, Object>>();               for (int j = 0; j < listTwo.size(); j++) {                      if (listTwo.get(j).get("pid").toString()                           .equals(listOne.get(i).get("id").toString())) {                          List<Map<String, Object>> minlist = new ArrayList<Map<String, Object>>();                          for (int k = 0; k < listThree.size(); k++) {                           Map<String, Object> minMap = new HashMap<String, Object>();                           if (listThree.get(k).get("pid").toString()                                   .equals(listTwo.get(j).get("id").toString())) {                               minMap.put("id", listThree.get(k).get("id"));                               minMap.put("name", listThree.get(k).get("module"));                               if (validateRightMask(listThree, authCode, k) != -1) {                                   minMap.put("checked"true);                               } else {                                   minMap.put("checked"false);                               }                               minlist.add(minMap);                           }                       }                       Map<String, Object> midMap = new HashMap<String, Object>();                       midMap.put("id", listTwo.get(j).get("id"));                       midMap.put("name", listTwo.get(j).get("module"));                       midMap.put("children", minlist);                       if (validateRightMask(listTwo, authCode, j) != -1) {                           midMap.put("checked"true);                       } else {                           midMap.put("checked"false);                       }                       midList.add(midMap);                   }               }               Map<String, Object> rootMap = new HashMap<String, Object>();               rootMap.put("id", listOne.get(i).get("id"));               rootMap.put("name", listOne.get(i).get("module"));               rootMap.put("children", midList);               if (validateRightMask(listOne, authCode, i) != -1) {                   rootMap.put("checked"true);               } else {                   rootMap.put("checked"false);               }               resultList.add(rootMap);           }       }          /**       * @function 验证authCode中是否有list中的权限码       * @author 皮锋       * @date 2016/8/26       * @param list       * @param authCode       * @param i       * @return int       */       private int validateRightMask(List<Map<String, Object>> list,               Map<String, Object> authCode, int i) {           String rightMask = authCode.get("auth_code") != null ? authCode.get(                   "auth_code").toString() : "";           if (!StringUtils.isEmpty(rightMask)) {               rightMask = rightMask.replace(";"",");               String[] arry = rightMask.split(",");               for (int j = 0; j < arry.length; j++) {                   String arryRightMask = arry[j];                   String listRightMask = list.get(i).get("id").toString();                   if (arryRightMask.equals(listRightMask)) {                       return 1;                   }               }           } else {               return -1;           }           return -1;       }  

4) dao层查询数据库获得用户权限

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

5)根据用户的权限码用freemarker标签控制页面功能模块是否显示

a.freemarkerxml文件中的配置

[html]  view plain  copy <bean id="freemarkerConfig"             class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">           <!--模板加载路径-->           <property name="templateLoaderPath">               <value>/WEB-INF/ftl/</value>           </property>           <property name="freemarkerVariables">               <map>                   <entry key="xml_escape" value-ref="fmXmlEscape"/>               </map>           </property>           <property name="freemarkerSettings">               <props>                   <prop key="tag_syntax">auto_detect</prop>                   <prop key="template_update_delay">0</prop>                   <prop key="default_encoding">UTF-8</prop>                   <prop key="output_encoding">UTF-8</prop>                   <prop key="locale">zh_CN</prop>                   <prop key="date_format">yyyy-MM-dd</prop>                   <prop key="time_format">HH:mm:ss</prop>                   <prop key="number_format">0.######</prop>                   <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>                   <!--空值处理-->                   <prop key="classic_compatible">true</prop>                   <!--自动导入ftl模板,并以“base”别名作为命名空间-->                   <prop key="auto_import">inc/spring.ftl as base</prop>               </props>           </property>       </bean>          <bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape"/>          <bean id="freeMarkerViewResolver"             class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">           <property name="suffix" value=".html"/>           <property name="cache" value="false"/>           <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"/>           <property name="contentType" value="text/html;charset=UTF-8"></property>           <!--fixed Exception:Cannot expose session attribute 'substoreid' because of an existing model -->           <property name="allowSessionOverride" value="true"/>           <property name="exposeRequestAttributes" value="true"/>           <property name="exposeSessionAttributes" value="true"/>           <property name="exposeSpringMacroHelpers" value="true"/>           <!-- 此变量值为pageContext.request, 页面使用方法:request.contextPath -->           <property name="requestContextAttribute" value="request"/>                      <property name="attributesMap">                 <map>                     <!-- 定义Freemarker方法的名称 -->                     <entry key="menucall">                         <!-- 关联到我们之前定义的工具类 -->                         <bean class="com.leike.util.MenuFunction" />                     </entry>                 </map>             </property>         </bean>  

b.写个类继承TemplateMethodModel类,实现freemarker自定义方法,用于实现控制页面模块是否显示

登陆的时候把用户权限码存入session中,然后从session中取权限。下面是一个例子:

[java]  view plain  copy 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

例如:

[html]  view plain  copy <#if menucall(1,122)>       <li style="line-height: 250%">           <a href="#" id="booknew"><i class="glyphicon"></i>预订</a>       </li>   </#if>  

以上就是对用户的访问模块(权限)进行控制的大体实现。

转载请注明原文地址: https://www.6miu.com/read-53442.html

最新回复(0)