SSM實現權限管理(三)

勿以惡小而爲之,勿以善小而不爲--------------------------劉備

勸諸君,多行善事積福報,莫作惡

上一章簡單介紹了 Servlet實現RBAC權限管理(二) ,如果沒有看過,請觀看上一章

在學習這一章節之前,一定要觀看上一章節的內容,代碼和思路,與上一章節類似,也需要掌握 SSM框架的相應知識。

如果不瞭解 SSM框架的相應知識,可以觀看 老蝴蝶以前寫的文章。

一. 準備階段

一.一 數據庫準備階段

準備與上一章節的數據庫結構和內容都一樣,只是將權限表 privilege 的url 地址改變了一下,由 servlet 訪問路徑改變成了 springmvc 訪問路徑。

有圖片

一.二 SSM框架搭建和前端頁面

SSM框架,採用 Maven 方式進行搭建,所用到依賴和配置文件,均採用SSM整合時的內容,

詳細可以看: Maven整合SSM項目(七)

頁面也採用上一章節的頁面信息。

框架搭建後的目錄結構如圖所示:

有圖片

二. 權限認證

二.一 認證和授權

二.一.一 認證

二.一.一.一 認證的 前端js 頁面

html 頁面:

有圖片

腳本代碼:

$(function(){
		$("#submit").click(function(){
			var code=$("#code").val();
			var password=$("#password").val();
			
			var info=new Object();
			//傳入進去,員工的id編號
			info.code=code;
			info.password=password;
			
			$.post("${pageContext.request.contextPath}/User/login",info,function(data){
				if(data.response_status){
					alert("登錄成功");
					window.location.href="${pageContext.request.contextPath}/Main/toMain";
				}else{
					if(data.error_msg=="001"){
						alert("用戶名或者密碼錯誤");
					}
				}
			},"json")
			
		})
	})

二.一.一.二 後端登錄處理

在 UserAction 下面的 login() 方法裏面。

@RequestMapping("/login")
	@ResponseBody
	public Map<String,Object> login(User userInfo,HttpSession session){
		//將請求信息,封裝到對象裏面。
		Map<String,Object> map=new HashMap<String,Object>();
		//從數據庫中查詢密碼
		User user=userService.login(userInfo);
		
		if(user!=null){
			//說明登錄成功,放置到session裏面
			session.setAttribute("loginUser",user);
			
			//查詢一下,該員工的 按鈕權限信息。
			List<Privilege> privilegeList= privilegeService.getPrivilegeByUId(user.getId(),2);
			
			List<String> priCodeList=new ArrayList<String>();
			for(Privilege pri:privilegeList){
				if(pri.getPercode()!=null){
					//放置標識
					priCodeList.add(pri.getPercode());
				}
			
			}
			//將權限轉換成 json 字符串
			ObjectMapper objMapper=new ObjectMapper();
			Map<String,List<String>> priCodeMap=new HashMap<String,List<String>>();
			priCodeMap.put("data", priCodeList);
			String priValueString="";
			try {
				priValueString = objMapper.writeValueAsString(priCodeMap);
			} catch (JsonProcessingException e) {
				// TODO 自動生成的 catch 塊
				e.printStackTrace();
			}
			session.setAttribute("privilegeList",priValueString);
			
			//登錄成功
			map.put("response_status", true);
			
		}else{
			//代碼爲001,表示用戶名或者密碼錯誤
			map.put("response_status", false);
			map.put("error_code","101");
		}
		
		return map;
		
	} 

二.一.二 授權

二.一.二.一 左側菜單展示

1.html 頁面元素

有圖片

2.js 腳本處理

有圖片

3.後端的 Mapper 查詢, 在 PrivilgeMapper.xml 裏面。

 <select id="findByUid" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from privilege a where a.id in (
		select rp.pid from user_role ur left join role_privilege rp
		on ur.rid=rp.rid
		where ur.uid=#{uId,jdbcType=INTEGER}
	)
	<if test="type != null and type !=''" >
      and a.type=#{type,jdbcType=INTEGER}
    </if>
  </select>

二.一.二.二 部門表按鈕顯示

與前面是一致的.

1 . 設置標識

<script>
		//獲取權限 
		var privilegeList='<%=session.getAttribute("privilegeList")%>';	
		//console.log("值是:"+privilegeList+","+typeof(privilegeList));
		var objPrivilegeList=JSON.parse(privilegeList);
		$.each(objPrivilegeList.data,function(idx,item){
			//將標識存放在 sessionStorage 裏面,進行暫時的保存。 
			sessionStorage.setItem(item,true);
		})
	</script>
<script type="text/javascript" src="${pageContext.request.contextPath}/static/js/dept.js"></script>

2 . 通過標識,對部門表的按鈕元素進行顯示或者隱藏

有圖片

二.二 權限驗證測試

通過對 admin,yuejl,yuezl 三個不同的角色進行登錄,可以正常地相應的菜單權限和按鈕權限。

也同樣,需要處理過濾器,只是在 SpringMVC 裏面,叫做攔截器。

關於攔截器的使用,可以看老蝴蝶以前寫得文章: SpringMVC的攔截器(十四)

二.三. 登錄和授權攔截器

二.三.一 編寫攔截器 LoginInterceptor

package com.yjl.action;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.yjl.pojo.Privilege;
import com.yjl.pojo.User;
import com.yjl.service.PrivilegeService;
/**
 * 
 * @author 兩個蝴蝶飛
 *
 * 登錄和授權攔截器
 */
public class LoginInterceptor implements HandlerInterceptor{
	
	@Autowired
	private PrivilegeService privilegeService;
	//不需要登錄驗證的url
		private static List<String> noLoginValidateUrl;
		//不需要權限驗證的url
		private static List<String> noPriValidateUrl;
		
		//跳轉到的登錄頁面
		private static String LOGIN_URL;
		//沒有權限的界面
		private static String NO_PRIVILEGE_URL;
		
		static{
			noLoginValidateUrl=new ArrayList<String>();
			
			//靜態資源
			noLoginValidateUrl.add("/static/");
			//登錄頁面
			noLoginValidateUrl.add("/User/toLogin");
			//登錄方法
			noLoginValidateUrl.add("/User/login");
			
			
			noPriValidateUrl=new ArrayList<String>();
			
			noPriValidateUrl.add("/Main/toMain");
			//查詢權限
			
			
			noPriValidateUrl.add("/Privilege/getPrivilegeByUId");
			//退出
			noPriValidateUrl.add("/User/logout");
			
			LOGIN_URL="/WEB-INF/jsp/login.jsp";
			
			NO_PRIVILEGE_URL="/WEB-INF/jsp/noPrivilege.jsp";
		}
		
		
	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		// TODO 自動生成的方法存根
		
	}

	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		// TODO 自動生成的方法存根
		
	}

	@Override
	public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object arg2) throws Exception {

		//獲取Session
		HttpSession session=req.getSession();
		
		//請求路徑
		String realPath=req.getRequestURI();
		System.out.println("地址是:"+realPath);
		
		//驗證是否在 不需要驗證登錄的url裏面
		if(isContain(realPath,1)){
			return true;
		}
		//如果爲空,表示沒有登錄
		if(session.getAttribute("loginUser")==null){
			req.getRequestDispatcher(LOGIN_URL).forward(req,resp);
			return false;
		}else{
			
			//不需要驗證權限
			if(isContain(realPath,2)){
				return true;
			}
			//如果不爲空,表示登錄了。
			//重新獲取全部權限 , 需要緩存, 這兒不用緩存。
			User user=(User)session.getAttribute("loginUser");
			List<Privilege> privilegeList=privilegeService.getPrivilegeByUId(user.getId(),null);
			if(privilegeList!=null&&privilegeList.size()>0){
				boolean isHavePri=false;
				for(Privilege pri:privilegeList){
					if(pri.getUrl()!=null){
						if(realPath.contains(pri.getUrl())){
							isHavePri=true;
							break;
						}
					}
				}
				if(isHavePri){
					//放行
					return true;
				}else{
					req.getRequestDispatcher(NO_PRIVILEGE_URL).forward(req,resp);
					return false;
				}
			}
			return false;
			
		}
		
	}
	private boolean isContain(String realPath,int type){	
		List<String> urls;
		if(type==1){
			urls=noLoginValidateUrl;
		}else{
			urls=noPriValidateUrl;
		}
		
		boolean flag=false;
		
		for(String url:urls){
			//包括,返回-1
			if(realPath.indexOf(url)!=-1){
				flag=true;
				break;
			}
		}
		return flag;
		
	}
}


二.三.二 配置攔截器

在springmvc.xml 配置文件中進行配置

有圖片

按照上一章節的方式進行測試,發現測試正確,不同的用戶具有不同的角色,老蝴蝶這兒就不再次貼圖了。

本章節的代碼鏈接爲:

鏈接:https://pan.baidu.com/s/1PChrWK9l02ANccerzc7rsg 
提取碼:iwvj

謝謝您的觀看,如果喜歡,請關注我,再次感謝 !!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章