登录拦截(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快乐!!!可惜我错过了整个纪元。啦啦啦,各位下个博客见!

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