基于Cookie使用过滤器实现客户每次访问只登录一次
相信大家在各大网站都会遇到,登录时,在登录框出现下次免登陆/一个月免登陆的类似选项,本文就是讲解如何实现,在这记录一下,也算是做个备忘录合集,如果文中有错,欢迎大家指出
为啥说自登陆一次呢,因为当访问某个页面时,如果第一次自动登录失败时,你下次刷新访问时还再次走自动登录流程,就会出现死循环。
本文代码示例框架为SpringMVC,下面就讲解实现该功能的需要掌握哪些知识:cookies与过滤器
1.cookies
何为Cookies:Cookies为Web应用程序保存用户相关信息提供了一种有用的方法。例如,当用户访问您的站点时,您可以利用Cookie保存用户首选项或其他信息,这样,当用户下次再访问您的站点时,应用程序就可以检索以前保存的信息。
我们看一下是如何保存cookies和如何删除cookies
保存cookies
StringnewUserName=null; try{ newUserName=URLEncoder.encode(username,"UTF-8");//把用户名转码,防止用户名是中文,cookies保存中文取出会乱码 }catch(UnsupportedEncodingExceptione){ e.printStackTrace(); } CookienameCookie=newCookie("username",newUserName); StringpwdMd5Cook=MD5Util.MD5(Pwd); CookiepwdCookie=newCookie("pwd",pwdMd5Cook);//保存加密后的密码 nameCookie.setMaxAge(60*60*24*365);//用户名保存一年 pwdCookie.setMaxAge(60*60*24*30);//密码保存30天 //发送Cookie信息到浏览器 response.addCookie(nameCookie); response.addCookie(pwdCookie);
删除cookies,删除很简单,但值得注意的时,删除cookies,跟保存cookies一定要在同一个控制层,不然会找不到保存的cookies,导致删除不了
Cookiecookie=newCookie("pwd",null); cookie.setMaxAge(0);//删除密码cookie response.addCookie(cookie);
2.Filter-过滤器
Filter也称之为过滤器,它是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp,Servlet,静态图片文件或静态html文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
实现方法:继承Filter接口,并实现其doFilter方法。在web.xml文件中对编写的filter类进行注册,并设置它所能拦截的资源
指定一个过滤器。 用于为过滤器指定一个名字,该元素的内容不能为空。 元素用于指定过滤器的完整的限定类名。 元素用于为过滤器指定初始化参数,它的子元素 指定参数的名字, 指定参数的值。 在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。 元素用于设置一个Filter所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet名称和资源访问的请求路径 子元素用于设置filter的注册名称。该值必须是在 元素中声明过的过滤器的名字 设置filter所拦截的请求路径(过滤器关联的URL样式) 指定过滤器所拦截的Servlet名称。 suicaiFilter com.suicai.filter.suicaiFilter suicaiFilter /*
下面看一下实际应用代码:
publicclasssuicaiFilterimplementsFilter{ @Override publicvoiddestroy(){ } @Override publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{ HttpServletRequestreq=(HttpServletRequest)request; HttpServletResponseres=(HttpServletResponse)response; HttpSessionsession=req.getSession(); StringrequestURI=req.getRequestURI(); Stringparam=req.getQueryString(); Stringurl=req.getServletPath(); if(param!=null){ url=url+"?"+param; } if(requestURI.contains("js")||requestURI.contains("css")||requestURI.contains("images")){ //不过滤css,js,images等静态资源 chain.doFilter(request,response); }elseif(requestURI.contains("/info/")||requestURI.contains("/gys/")){ //过滤前台访问页面,跟前台个人中心(供应商后台),自动登录一次,登录不成功不进行操作,个人中心登录不成功,则跳到登录页面 ProviderInfoproviderInfo=(ProviderInfo)session.getAttribute("providerInfo_gys"); StringIsAutomaticLogin=(String)session.getAttribute("IsAutomaticLogin");//是否已经走过自动登录流程标识 if(requestURI.contains("/info/")&&!requestURI.contains("/login")){ //访问门户等不需要必须登录的(登录除外),只尝试登录一次,如果不成功,不进行操作 if(providerInfo==null&&IsAutomaticLogin==null){ req.getSession().setAttribute("goURL",url); res.sendRedirect(req.getContextPath()+"/common/automaticLogin"); }elseif(providerInfo==null&&IsAutomaticLogin!=null){ chain.doFilter(request,response); }else{ chain.doFilter(request,response); } }elseif(requestURI.contains("/gys/")){//访问个人中心,自登陆一次,不成功跳转到登录页面 if(providerInfo==null&&IsAutomaticLogin==null){ req.getSession().setAttribute("goURL",url); res.sendRedirect(req.getContextPath()+"/common/automaticLogin"); }elseif(providerInfo==null&&IsAutomaticLogin!=null){ session.setAttribute("redirectUrl",url); res.sendRedirect(req.getContextPath()+"/login.jsp?redirectUrl="+url); }else{ chain.doFilter(request,response); } }else{ chain.doFilter(request,response); } }else{ //不过滤 chain.doFilter(request,response); } } @Override publicvoidinit(FilterConfigarg0)throwsServletException{ } }
从代码中可知,需要一个是否已经自动登录过的标识(IsAutomaticLogin),该标识是在走自动登录时(不管成不成功)保存起来的
3.结合上面提供知识,下面为整体代码展示,如发现不对地方,欢迎大家指出
@Controller @RequestMapping("/common") publicclassCommonController{ /** *自动登录方法 *@paramrequest *@paramresponse *@paramusername *@parampwd *@paramProviderInfo供应商账户信息model *@return */ @RequestMapping("/automaticLogin") publicStringautomaticLogin(HttpServletRequestrequest,ServletResponseresponse,@CookieValue(value="username",required=false)Stringusername,@CookieValue(value="pwd",required=false)Stringpwd,ProviderInfoProviderInfo){ //保存需求登录前的链接 StringgoURL=(String)session.getAttribute("goURL"); if(username==null){//cookies中没有用户名,肯定不需要自动登录 session.setAttribute("IsAutomaticLogin","0"); return"redirect:"+goURL; }else{ try{ username=URLDecoder.decode(username,"UTF-8");//转义,防止中文 }catch(UnsupportedEncodingExceptione){ e.printStackTrace(); } } //cookie失效session一定为空,因为登录时,一定会把用户名保存在cookie中 if("".equals(username)||username==null){//使用session登录不了,不进行任何操作,不在进入这个方法 session.setAttribute("IsAutomaticLogin","0"); return"redirect:"+goURL; }else{ //cookie中没有密码,判断session为不为空,如果为空,说明没有登录,如果不为空,说明,用户是选择不记住密码登录(所以cookie中没有密码) if("".equals(pwd)||pwd==null){ ProviderInfocustomer1=(ProviderInfo)session.getAttribute("providerInfo_gys"); if(customer1==null){//使用session登录不了,不进行任何操作,不在进入这个方法 session.setAttribute("IsAutomaticLogin","0"); return"redirect:"+goURL; }else{ //已经登录,不再进入这个方法 return"redirect:"+goURL; } }else{ //cookie中有密码,判断session为不为空,如果为空,说明没有登录,如果不为空,说明已经登录 ProviderInfocustomer1=(ProviderInfo)session.getAttribute("providerInfo_gys"); if(customer1==null){//当前没有登录,调用cookies中的用户名跟密码进行登录 //进行自动登录操作,登录成功后返回原来页面 ProviderInfocustomer3=ValidateDate(username); customer3.setPwd(pwd); customer3.setAccountType(6); ProviderInfocustomer2=infoService.login(customer3);//调用登录方法 if(customer2==null){//自动登录失败,不再进入这个方法 session.setAttribute("IsAutomaticLogin","0"); return"redirect:"+goURL; }else{ //登陆成功保存客户信息到session session.setAttribute("providerInfo_gys",customer2); return"redirect:"+goURL; } }else{ return"redirect:"+goURL; } } } } /** *用户登陆 *@paramrequest *@paramresponse *@paramcus *@return */ @RequestMapping("/UserLogin") @ResponseBody publicMapgoLogin(HttpServletRequestrequest,HttpServletResponseresponse,@ModelAttribute("ProviderInfo")ProviderInfocus){ /*省略一些逻辑判断*/ cus.setPwd(MD5Util.MD5(Pwd)); ProviderInfoproviderInfo=infoService.login(cus); Map cookieMap=newHashMap (); if(providerInfo==null){ //登陆失败,重新跳转到登陆页面 map.put("error","密码错误"); returnmap; }else{ StringnewUserName=null; if(remember_me.equals("1")){//有选择一个月免登录 try{ newUserName=URLEncoder.encode(username,"UTF-8"); }catch(UnsupportedEncodingExceptione){ e.printStackTrace(); } CookienameCookie=newCookie("username",newUserName); StringpwdMd5Cook=MD5Util.MD5(Pwd); CookiepwdCookie=newCookie("pwd",pwdMd5Cook);//保存加密后的密码+"create" nameCookie.setMaxAge(60*60*24*365);//用户名保存一年 pwdCookie.setMaxAge(60*60*24*30);//密码保存30天 //发送Cookie信息到浏览器 response.addCookie(nameCookie); response.addCookie(pwdCookie); session.setAttribute("IsAutomaticLogin",null); }else{//没有选择,删除上次可能已经选择自动登录时的密码 Cookie[]cookies=request.getCookies(); if(null!=cookies){ for(Cookiecookie:cookies){ cookieMap.put(cookie.getName(),cookie); } } if(cookies!=null){ for(inti=0;i cookieMap=newHashMap (); Cookie[]cookies=request.getCookies(); if(null!=cookies){ for(Cookiecookie:cookies){ cookieMap.put(cookie.getName(),cookie); } } if(cookies!=null){ for(inti=0;i 以上所述是小编给大家介绍的基于Cookie使用过滤器实现客户每次访问只登录一次,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!