登錄攔截(2020.5.20貢獻篇)

登錄攔截實現步驟

一:前提條件

此時我們的ssj項目已經搭建完成,最好是簡單的crud功能已經完成。這裏簡單介紹一下思路:在我們新增或者完善一個項目的功能時我們要有大概的思路。那麼什麼是登錄攔截呢,互聯網時代我們在生活中經常接觸,可以說手機app及網頁上必不可少的一項。在我們進入app或淘寶網頁時會讓你先登錄個人賬號,此時一般必有用戶名和密碼兩項,當然現在很多會加上手機驗證碼。本文先介紹驗證用戶名和密碼,當我們在前臺頁面填寫用戶名和密碼並點擊提交後,後臺根據用戶名查找user數據,若不存在就提示用戶名不存在,若用戶名存在就拿該user數據庫信息的密碼和輸入的密碼對比(這裏的密碼加密及解密就不贅述了)若密碼正確則驗證通過,若錯誤則提示密碼錯誤。該項功能需要前端頁面+controller+loginInterceptor與數據庫交互共同完成。loginInterceptor在每個controller方法使用時都會驗證攔截。

二:登錄攔截頁面


這是我的項目登陸頁面(驗證碼本文不多講,如有需要後續會寫一篇驗證碼相關的小功能),當用戶輸入用戶名密碼後,點擊提交會發送一個ajax請求,此時controller層接收到用戶名和密碼。

三:controller層業務操作

    @RequestMapping("login")
	@ResponseBody
	public Map<String,Object> login(
			String username,
			String password,
			String code,
			HttpSession session
			){
		Map<String,Object> result = new HashMap<String, Object>();
		User userByUsername = null;
		if(StringUtils.isNotBlank(username)) {
			 userByUsername = userService.findByUserName(username);
			//1驗證用戶名
			if(userByUsername == null) {
				result.put("success", false);
				result.put("msg", "用戶名不存在!");
				return result;
			}
		}
		
		//2驗證驗證碼
		if(StringUtils.isNotBlank(code)) {
			String checkCode = (String) session.getAttribute("checkCode");
			if(!checkCode.trim().equals(code.trim())) {
				result.put("success", false);
				result.put("msg", "用戶驗證碼不正確!");
				return result;
			}
		}else {
			result.put("success", false);
			result.put("msg", "用戶驗證碼不能爲空!");
			return result;
		}
		//3驗證密碼
		if(!MD5Util.verify(password, userByUsername.getPassword())){//密碼不對
			result.put("success", false);
			result.put("msg", "用戶密碼不正確!");
			return result;
		}else {//密碼對
			session.setAttribute("user", userByUsername); 
			result.put("success", true);
			result.put("msg", "登陸成功");
			return result;
		}

controller層邏輯:當我們在前臺頁面填寫用戶名和密碼並點擊提交後,後臺根據用戶名查找user數據,若不存在就提示用戶名不存在,若用戶名存在就拿該user數據庫信息的密碼和輸入的密碼對比(這裏的密碼加密及解密就不贅述了)若密碼正確則驗證通過,若錯誤則提示密碼錯誤。
此時驗證通過與否的關鍵代碼爲:session.setAttribute(“user”, userByUsername); 當我們所有驗證都通過是表明我們的用戶是存在的,那麼我們將用戶信息放到session會話中,然後在loginInterceptor中驗證。

四:LoginInterceptor層業務操作

@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		HttpSession session = request.getSession();
		
		User user = (User) session.getAttribute("user");//其實就是查詢session中是否有user
		if(user != null) {
			return true;
		}else {//判斷是不是ajax請求//XMLHttpRequest//X-Requested-With
			String head = request.getHeader("X-Requested-With");
			if(StringUtils.isNotBlank(head) && head.equals("XMLHttpRequest")) {
				Map<String, Object> result = new HashMap<String, Object>();
				result.put("code",12345);
				JsonUtil.outJson(response, result);
			}else {
				response.sendRedirect(request.getServletContext().getContextPath()+"/login.jsp");
			}
			return false;
		}
	}

這裏我們新建一個LoginLnterceptor類,繼承HandlerInterceptorAdapter 重寫preHandle方法,這裏我們可以重寫的方法有:
preHandle:在控制器方法調用前執行,返回值爲是否中斷,true,表示繼續執行(下一個攔截器或處理器),false則會中斷後續的所有操作,所以我們需要使用response來響應請求。
postHandle:在控制器方法調用後,解析視圖前調用,我們可以對視圖和模型做進一步渲染或修改。
afterCompletion:整個請求完成,即視圖渲染結束後調用,這個時候可以做些資源清理工作,或日誌記錄等。
afterConcurrentHandlingStarted:當Controller中有異步請求方法的時候會觸發該方法時,異步請求先支持preHandle、然後執行afterConcurrentHandlingStarted。
注意!!!這裏我們使用的是preHandler,在controller方法調用前執行,當session中user不爲空時,說明user信息存在即登陸成功,不需要攔截,則返回true。反之返回false。那就有個問題了:preHandle會攔截controller層的所有方法,那麼login方法豈不是一直都進不去嗎?因爲只有login方法成功後纔會在session中放入user。那麼這個問題就需要配置spring-mvc的攔截器白名單了。白名單無需驗證即可通過。
其實當我們在判斷用戶爲空即登錄不成功後又通過請求頭的方式String head = request.getHeader(“X-Requested-With”);判斷了該請求是不是ajax請求。

如果是ajax請求呢,用戶是不會跳轉的,雖然用戶的操作被攔截,但是用戶卻不知道。所以我們可以在攔截成功的時候,響應一個字符。(JsonUtil.outJson(response, result);)這裏我向前臺傳遞一個map集合值爲:12345。當前臺收到後可以提醒用戶登陸失敗。

如果不是ajax請求則可以直接獲取項目上下文路徑後response重定向到login.jsp。讓用戶重新登陸。

五:spring-mvc的攔截器及白名單配置

寫到這裏小編的電腦硬盤出了些故障,配置信息等電腦修好後再補上吧。

六:寫在最後

總結登陸攔截器,其實就是在controller層每個方法之前加上一個驗證即interceptor的session驗證。當驗證通過後可以在一次session回話中訪問任何方法及跳轉頁面。本文爲小編個人理解所做,如有錯誤請聯繫我修改或刪除。
最後的最後祝大家2020520快樂!!!可惜我錯過了整個紀元。啦啦啦,各位下個博客見!

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