一、概念
權限管理就是管理用戶對於資源的操作,CRM(客戶管理軟件)基於角色操作權限來實現的,就是用戶通過角色和權限來實現的。
二、數據庫
一共涉及5張表
三張主表
user表(用戶表)
role表(角色表)
module表(模塊表,資源表)
兩張中間表
user_role表(user,role中間表)
role_module表(role,module中間表)
1 --創建用戶表 2 create table users( 3 --主鍵 4 id number(10) primary key, 5 --用戶名 6 username varchar2(100), 7 --密碼 8 password varchar2(100), 9 --地址 10 address varchar2(100) 11 ); 12 --創建角色表 13 create table role( 14 --主鍵 15 id number(10) primary key, 16 --角色名稱 17 name varchar2(100) 18 ); 19 --創建模塊表 20 create table module( 21 --主鍵 22 id number(10) primary key, 23 --模塊名稱 24 name varchar2(100), 25 --模塊級別 26 level_ number(3), 27 --父模塊id 28 pid number(10), 29 --模塊路徑 30 url varchar2(100) 31 ); 32 --創建用戶角色中間表 33 create table user_role( 34 --用戶表外鍵 35 u_id number(10), 36 --角色表外鍵 37 r_id number(10) 38 ); 39 --創建角色模塊中間表 40 create table role_module( 41 --角色表外鍵 42 r_id number(10), 43 --模塊表外鍵 44 m_id number(10) 45 ); 46 --往用戶表插入數據 47 insert into users values(1,'zhangsan','123456','鄭州'); 48 insert into users values(2,'lisi','123456','鄭州'); 49 --往角色表插入數據 50 insert into role values(1,'普通用戶'); 51 insert into role values(2,'管理員'); 52 --往模塊表插入數據 53 insert into module values(1,'系統管理',1,null,null); 54 insert into module values(2,'訂單管理',1,null,null); 55 insert into module values(3,'用戶管理',2,1,'user/list.do'); 56 insert into module values(4,'角色管理',2,1,'role/list.do'); 57 insert into module values(5,'模塊管理',2,1,'mod/list.do'); 58 insert into module values(6,'出庫單管理',2,2,'ckd/list.do'); 59 insert into module values(7,'入庫單管理',2,2,'rkd/list.do'); 60 --為張三用戶賦予管理員的角色,為李四賦予普通用戶的角色 61 insert into user_role values(1,2); 62 insert into user_role values(2,1); 63 --讓管理員可以看到所有的菜單 普通用戶只能看到訂單管理下所有的菜單 64 insert into role_module values(2,1); 65 insert into role_module values(2,2); 66 insert into role_module values(2,3); 67 insert into role_module values(2,4); 68 insert into role_module values(2,5); 69 insert into role_module values(2,6); 70 insert into role_module values(2,7); 71 insert into role_module values(1,2); 72 insert into role_module values(1,6); 73 insert into role_module values(1,7); 74 select * from users; 75 select * from role; 76 select * from user_role; 77 select * from module; 78 select * from role_module;
三、權限管理的步驟
第一步,用戶登陸成功之后,根據用戶的id查詢出用戶所能操作的模塊,模塊一般包含兩級。
sql語句的作用:根據用戶id查詢用戶能操作的模塊
查詢出來之后,把用戶能操作的模塊封裝到List中:
第二步,在登陸之后跳轉到主界面,用jstl標簽庫把用戶能操作的模塊動態的遍歷出來
第三步,登陸校驗
1、用戶登陸成功之后,把當前用戶對象放置到session中
2、聲明用戶登陸的攔截器
1 package com.aaa.ssm.interceptor; 2 import com.aaa.ssm.common.Constants; 3 import com.aaa.ssm.entity.Users; 4 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import javax.servlet.http.HttpServletRequest; 5 import javax.servlet.http.HttpServletResponse; 6 import javax.servlet.http.HttpSessionimport java.util.List; 7 /** 8 * 用戶登錄校驗攔截器 9 */ 10 public class LoginInterceptor extends HandlerInterceptorAdapter { 11 private List<String> allowUrls; 12 @Override 13 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 14 throws Exception { 15 //獲取當前請求的路徑 16 String path = request.getServletPath(); 17 //判斷當前請求的路徑是否在運行直接訪問的路徑中,如果在直接返回true 18 if(allowUrls.contains(path)){ 19 return true; 20 } 21 //獲取Session 22 HttpSession session = request.getSession(); 23 //獲取Session中的用戶對象 24 Users user = (Users)session.getAttribute(Constants.SESSION_USER); 25 //判斷user對象是否為空,如果為空跳轉到登錄界面 26 if(user==null){ 27 //跳轉到登錄界面 28 response.sendRedirect(request.getContextPath()+"/login.jsp"); 29 return false; 30 }else{ 31 return true; 32 } 33 } 34 public List<String> getAllowUrls() { 35 return allowUrls; 36 } 37 public void setAllowUrls(List<String> allowUrls) { 38 this.allowUrls = allowUrls; 39 } 40 }
3、在spring mvc主配置文件中聲明攔截器
第四步、權限校驗
1、用戶登陸成功之后把用戶能操作的所有的路徑信息放置到list中,並把該信息存儲到session中
1 /** 2 * 查詢用戶能操作的所有二級模塊的命名空間 3 * @param moules 4 * @return 5 */ 6 public List<String> queryPermitUrls (List<Module> moules){ 7 List<String> strs = new ArrayList<String>(); 8 for(Module oneModule : moules){ 9 List<Module> twoModules = oneModule.getChildren(); 10 for(Module twoModule : twoModules){ 11 String url = twoModule.getUrl(); 12 strs.add(url.substring(0,url.indexOf("/"))); 13 } 14 } 15 return strs; 16 }
2、聲明用戶權限校驗的攔截器
1 package com.aaa.ssm.interceptor; 2 import com.aaa.ssm.common.Constants; 3 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 4 import javax.servlet.http.HttpServletRequest; 5 import javax.servlet.http.HttpServletResponse; 6 import javax.servlet.http.HttpSessionimport java.util.List; 7 /** 8 * 用戶權限校驗攔截器 9 */ 10 public class PermitInterceptor extends HandlerInterceptorAdapter { 11 private List<String> allowUrls; 12 @Override 13 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 14 throws Exception { 15 //先獲取請求的路徑 16 String path = request.getServletPath(); 17 //判斷當前請求的路徑是否在運行直接訪問的路徑中,如果在直接返回true 18 if(allowUrls.contains(path)){ 19 return true; 20 } 21 //判斷用戶當前的請求,在不在權限范圍之內 22 //可以根據用戶id查詢出來所有用戶能操作的模塊的路徑,把這些路徑放置到List集合中, 23 //讓后再判斷該list集合中有沒有當前請求的路徑,如果有的話 返回true繼續訪問,否則跳轉到權限不足界面 24 //上面做法的第一個問題:如果在攔截器中每次都查詢數據庫,前台基本上所有請求都會經過該攔截器,勢必響原先 25 //請求的訪問效率。我們可以在用戶登錄成功之后把用戶能操作的模塊的信息放置到session中,這樣在攔截每次都從 26 //session中獲取數據,速度就快多了。 27 HttpSession session = request.getSession(); 28 //獲取用戶能操作的模塊的命名空間 29 List<String> permitNamespaces = (List<String>)session.getAttribute(Constants.PERMIT_URLS); 30 //判斷path是否在permitNamespaces中,如果在證明有權限 返回true 否則返回false 跳轉到權限不足的界//獲取當前請求的路徑命名空間 31 String namespace = path.substring(1,path.lastIndexOf("/")); 32 if(permitNamespaces.contains(namespace)){ 33 return true; 34 }else{ 35 response.sendRedirect(request.getContextPath()+"/error.jsp"); 36 return false; 37 } 38 } 39 public List<String> getAllowUrls() { 40 return allowUrls; 41 } 42 public void setAllowUrls(List<String> allowUrls) { 43 this.allowUrls = allowUrls; 44 } 45 }
3、把攔截器加入到spring mvc 主配置文件中
總結:
動態菜單:
第一個要點:表結構和數據 用戶表 角色表 模塊表 用戶角色中間表 角色模塊中間表
第二個要點:用戶登錄成功之后,先根據的用戶id獲取用戶能操作的一級模塊,再循環遍歷一級模塊,把用戶 能操作的二級模塊封裝到一級模塊的children屬性中。
第三個要點:jsp界面使用兩個c:foreach把用戶能操作的菜單動態的輸出出來。
登錄校驗
第一個要點:用戶登錄成功之后,把當前的用戶對象放置到Session中
第二個要點:聲明登錄校驗的攔截器,需要不攔截一些特定的請求,如登錄請求。攔截器中獲取session,獲 取session中的用戶對象,如果用戶對象不存在,跳轉到登錄界面。存在,繼續訪問。
第三個要點:配置攔截器。
權限校驗 為了防止沒有權限的用戶通過其他手段直接請求控制器方法。
第一個要點:用戶登錄成功之后,把用戶能操作的命名空間保存到session中。List.
第二個要點:聲明權限校驗攔截器。需要不攔截一些特定的請求,如登錄請求。獲取sesson,獲取session的 用戶能操作的命名空間,獲取用戶的當前的請求路徑,根據請求路徑可以把命名空間截取出來。然后判斷用 戶當前請求的命名空間在不在session中保存用戶可操作的命名空間中。如果在直接訪問。不在跳轉到權限不 足的界面。