登录拦截(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快乐!!!可惜我错过了整个纪元。啦啦啦,各位下个博客见!
标签:用户名,20,2020.5,密码,session,user,put,拦截,result 来源: https://blog.csdn.net/weixin_46763029/article/details/106240707