框架ssm,使用拦截器+cookie+session来进行自动登录。
使用拦截器需要在pringmvc的配置文件中进行注册拦截器。
<!-- 注册拦截器 --> <mvc:interceptors> <mvc:interceptor> <!-- 拦截所有以admin为路径的请求 --> <mvc:mapping path="/admin/*"/> <bean class="org.seckill.common.LoginInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>拦截器的preHandle方法
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //首先从cookie里读取会话查看是否有,如果没有则验证 Cookie cookie = CookieTool.getCookieByName(request, "session"); if(cookie==null); else { if(request.getSession().getAttribute("UserName")==null)//进行设置会话 { request.getSession().setAttribute("UserName", cookie); response.sendRedirect("index"); return true;//不返回可能会导致重复重定向 } } if(null==request.getSession().getAttribute("UserName")) { //没有会话 if(request.getServletPath().contains("login"))//如果路径有login则不拦截该路径因为我的登录页面是admin/login return true; //request.getRequestDispatcher("/admin/login").forward(request, response); 请求转发 response.sendRedirect("login"); //请求重定向 return false;//进行拦截 } //有会话且是login页时 if(request.getServletPath().contains("login")||"/admin/".equals(request.getServletPath())) {//使其不进入login页面和/ response.sendRedirect("index"); } // System.out.println(request.getSession().getAttribute("UserName")); return true; }
然后就是登录控制器
@RequestMapping(value = "/login/sigin", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) @ResponseBody//注解返回类型为json public String sigin(Model model,String username,String password,String checked,HttpServletRequest request, HttpServletResponse response) { if(login.login(username, password()) != null)//判断账号密码正确 { if(checked.equals("true"))//判断是否选中自动 { CookieTool.addCookie(response, "session",username,(60*60*24*30));//添加cookie request.getSession().setAttribute("UserName", CookieTool.getCookieByName(request, "session")); } else { request.getSession().setAttribute("UserName", ussername); } return "ok"; } return "no"; }
上面用到了cookie工具类
public class CookieTool{ /** * 设置cookie(接口方法) * @param response * @param name cookie名字 * @param value cookie值 * @param maxAge cookie生命周期 以秒为单位 */ public static void addCookie(HttpServletResponse response,String name,String value,int maxAge){ Cookie cookie = new Cookie(name,value); cookie.setPath("/"); if(maxAge>0) cookie.setMaxAge(maxAge); response.addCookie(cookie); } /** * 根据名字获取cookie(接口方法) * @param request * @param name cookie名字 * @return */ public static Cookie getCookieByName(HttpServletRequest request,String name){ Map<String,Cookie> cookieMap = ReadCookieMap(request); if(cookieMap.containsKey(name)){ Cookie cookie = (Cookie)cookieMap.get(name); return cookie; }else{ return null; } } /** * 将cookie封装到Map里面(非接口方法) * @param request * @return */ private static Map<String,Cookie> ReadCookieMap(HttpServletRequest request){ Map<String,Cookie> cookieMap = new HashMap<String,Cookie>(); Cookie[] cookies = request.getCookies(); if(null!=cookies){ for(Cookie cookie : cookies){ cookieMap.put(cookie.getName(), cookie); } } return cookieMap; } }至此整个后台大致逻辑已经完成。
在拦截器进行对cookie的判断,如果有进行重定向(真实环境没那么简单需要许多的校验工作)
如果没有就再登录成功后设置cookie值。
下面看一下前端的主要代码
<div class="login-box-body"> <p class="login-box-msg">管理员登录</p> <div class="form-group has-feedback"> <input type="text" class="form-control" name="username" placeholder="账号"> <span class="glyphicon glyphicon-user form-control-feedback"></span> </div> <div class="form-group has-feedback"> <input type="password" class="form-control" name="password" placeholder="密码"> <span class="glyphicon glyphicon-lock form-control-feedback"></span> </div> <div class="form-group has-feedback"> <div style="float:right;"> <input type="checkbox" name="login">保持登录 </div> </div> <br><br> <div class="row"> <div class="col-xs-8"> <div class="checkbox icheck"> </div> </div> <!-- /.col --> <div class="col-xs-4"> <button type="button" class="btn btn-primary btn-block btn-flat">登录</button> </div> <!-- /.col --> </div> <!-- /.social-auth-links --> </div> <script> $(function(){ // $.post("") $("button").click(function(){ $.post("login/sigin",{ username:$("input[name='username']").val(), password:$("input[name='password']").val(), checked:$("input[name='login']").is(':checked') },function(data, textStatus){ if(data=="ok") { window.location.href="index"; } else{ alert("您输入的账号密码有误"); } }); }); }); </script>
真实项目中需要对cookie的键值对进行加密等处理,还要防止cookie挟制等安全问题。可能大型互联网项目的自动登录验证很复杂但是其主要的核心步骤应该差不多。