侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

基于Cookie使用过滤器实现客户每次访问只登录一次

技术  /  管理员 发布于 8年前   270

相信大家在各大网站都会遇到,登录时,在登录框出现下次免登陆/一个月免登陆的类似选项,本文就是讲解如何实现,在这记录一下,也算是做个备忘录合集,如果文中有错,欢迎大家指出

为啥说自登陆一次呢,因为当访问某个页面时,如果第一次自动登录失败时,你下次刷新访问时还再次走自动登录流程,就会出现死循环。

本文代码示例框架为Spring MVC,下面就讲解实现该功能的需要掌握哪些知识:cookies与过滤器

1.cookies

何为Cookies:Cookies为 Web 应用程序保存用户相关信息提供了一种有用的方法。例如,当用户访问您的站点时,您可以利用 Cookie 保存用户首选项或其他信息,这样,当用户下次再访问您的站点时,应用程序就可以检索以前保存的信息。

我们看一下是如何保存cookies和如何删除cookies

保存cookies

String newUserName = null;try {  newUserName = URLEncoder.encode(username, "UTF-8");//把用户名转码,防止用户名是中文,cookies保存中文取出会乱码} catch (UnsupportedEncodingException e) {  e.printStackTrace();}Cookie nameCookie = new Cookie("username", newUserName);String pwdMd5Cook = MD5Util.MD5(Pwd);Cookie pwdCookie = new Cookie("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,导致删除不了

Cookie cookie = new Cookie("pwd", null);cookie.setMaxAge(0);// 删除密码cookieresponse.addCookie(cookie);

2.Filter-过滤器

Filter也称之为过滤器,它是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

实现方法:继承Filter接口,并实现其doFilter方法。在web.xml文件中对编写的filter类进行注册,并设置它所能拦截的资源

<filter>指定一个过滤器。<filter-name>用于为过滤器指定一个名字,该元素的内容不能为空。<filter-class>元素用于指定过滤器的完整的限定类名。<init-param>元素用于为过滤器指定初始化参数,它的子元素<param-name>指定参数的名字,<param-value>指定参数的值。在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。<filter-mapping>元素用于设置一个 Filter 所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径<filter-name>子元素用于设置filter的注册名称。该值必须是在<filter>元素中声明过的过滤器的名字<url-pattern>设置 filter 所拦截的请求路径(过滤器关联的URL样式)<servlet-name>指定过滤器所拦截的Servlet名称。<filter>  <filter-name>suicaiFilter</filter-name>  <filter-class>com.suicai.filter.suicaiFilter</filter-class></filter><filter-mapping>  <filter-name>suicaiFilter</filter-name>  <url-pattern>/*</url-pattern></filter-mapping>

下面看一下实际应用代码:

public class suicaiFilter implements Filter {  @Override  public void destroy() {  }  @Override  public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {    HttpServletRequest req=(HttpServletRequest)request;    HttpServletResponse res=(HttpServletResponse)response;    HttpSession session = req.getSession();    String requestURI = req.getRequestURI();    String param = req.getQueryString();    String url = 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);    }else if(requestURI.contains("/info/")||requestURI.contains("/gys/")){      //过滤前台访问页面,跟前台个人中心(供应商后台),自动登录一次,登录不成功不进行操作,个人中心登录不成功,则跳到登录页面      ProviderInfo providerInfo = (ProviderInfo) session.getAttribute("providerInfo_gys");      String IsAutomaticLogin = (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");        }else if(providerInfo==null && IsAutomaticLogin != null ){          chain.doFilter(request, response);        }else{          chain.doFilter(request, response);        }      }else if(requestURI.contains("/gys/")){//访问个人中心,自登陆一次,不成功跳转到登录页面        if(providerInfo==null && IsAutomaticLogin == null){          req.getSession().setAttribute("goURL", url);          res.sendRedirect(req.getContextPath() + "/common/automaticLogin");        }else if(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  public void init(FilterConfig arg0) throws ServletException {  }}

从代码中可知,需要一个是否已经自动登录过的标识(IsAutomaticLogin),该标识是在走自动登录时(不管成不成功)保存起来的

3.结合上面提供知识,下面为整体代码展示,如发现不对地方,欢迎大家指出

@Controller@RequestMapping("/common")public class CommonController{  /**   * 自动登录方法   * @param request   * @param response   * @param username   * @param pwd   * @param ProviderInfo 供应商账户信息model   * @return   */  @RequestMapping("/automaticLogin")  public String automaticLogin(HttpServletRequest request,ServletResponse response,@CookieValue(value = "username", required = false) String username,@CookieValue(value = "pwd", required = false) String pwd,ProviderInfo ProviderInfo) {    // 保存需求登录前的链接    String goURL = (String) session.getAttribute("goURL");    if (username == null) {//cookies中没有用户名,肯定不需要自动登录      session.setAttribute("IsAutomaticLogin", "0");      return "redirect:" + goURL;    } else {      try {        username = URLDecoder.decode(username, "UTF-8");//转义,防止中文      } catch (UnsupportedEncodingException e) {        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) {        ProviderInfo customer1 = (ProviderInfo) session.getAttribute("providerInfo_gys");        if (customer1 == null) {// 使用session登录不了,不进行任何操作,不在进入这个方法          session.setAttribute("IsAutomaticLogin", "0");          return "redirect:" + goURL;        } else {          // 已经登录,不再进入这个方法          return "redirect:" + goURL;        }      } else {        // cookie中有密码,判断session为不为空,如果为空,说明没有登录,如果不为空,说明已经登录        ProviderInfo customer1 = (ProviderInfo) session.getAttribute("providerInfo_gys");        if (customer1 == null) {// 当前没有登录,调用cookies中的用户名跟密码进行登录          // 进行自动登录操作,登录成功后返回原来页面          ProviderInfo customer3 = ValidateDate(username);          customer3.setPwd(pwd);          customer3.setAccountType(6);          ProviderInfo customer2 = infoService.login(customer3);//调用登录方法          if (customer2 == null) {// 自动登录失败,不再进入这个方法session.setAttribute("IsAutomaticLogin", "0");return "redirect:" + goURL;          } else {// 登陆成功保存客户信息到sessionsession.setAttribute("providerInfo_gys",customer2);return "redirect:" + goURL;          }        } else {          return "redirect:" + goURL;        }      }    }  }  /**   * 用户登陆   * @param request   * @param response   * @param cus   * @return   */  @RequestMapping("/UserLogin")  @ResponseBody  public Map<String, Object> goLogin(HttpServletRequest request,HttpServletResponse response,@ModelAttribute("ProviderInfo") ProviderInfo cus) {    /*省略一些逻辑判断*/    cus.setPwd(MD5Util.MD5(Pwd));    ProviderInfo providerInfo = infoService.login(cus);    Map<String, Cookie> cookieMap = new HashMap<String, Cookie>();    if (providerInfo == null) {      // 登陆失败,重新跳转到登陆页面      map.put("error", "密码错误");      return map;    }else{      String newUserName = null;      if (remember_me.equals("1")) {// 有选择一个月免登录        try {          newUserName = URLEncoder.encode(username, "UTF-8");        } catch (UnsupportedEncodingException e) {          e.printStackTrace();        }        Cookie nameCookie = new Cookie("username", newUserName);        String pwdMd5Cook = MD5Util.MD5(Pwd);        Cookie pwdCookie = new Cookie("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 (Cookie cookie : cookies) {cookieMap.put(cookie.getName(), cookie);          }        }        if (cookies != null) {          for (int i = 0; i < cookies.length; i++) {if (cookieMap.containsKey("pwd")) {  Cookie cookie = new Cookie("pwd", null);  cookie.setMaxAge(0);// 删除密码cookie  response.addCookie(cookie);}          }        }      }      // 登陆成功,保存当前user信息,保存客户信息到session      map.put("ProviderInfo", providerInfo);      map.put("goURL", session.getAttribute("goURL"));      session.setAttribute("providerInfo_gys", providerInfo);      return map;    }else {      map.put("error", "该供应商账号不存在");      return map;    }  }  /**   * 注销   * @return   */  @RequestMapping("/logout")  public String logout(HttpServletResponse response) {    Map<String, Cookie> cookieMap = new HashMap<String, Cookie>();    Cookie[] cookies = request.getCookies();    if (null != cookies) {      for (Cookie cookie : cookies) {        cookieMap.put(cookie.getName(), cookie);      }    }    if (cookies != null) {      for (int i = 0; i < cookies.length; i++) {        if (cookieMap.containsKey("pwd")) {          Cookie cookie = new Cookie("pwd", null);          cookie.setMaxAge(0);// 删除密码cookie          response.addCookie(cookie);        }      }    }    session.setAttribute("providerInfo_gys", null);    return "/index";  }}

以上所述是小编给大家介绍的基于Cookie使用过滤器实现客户每次访问只登录一次,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对站的支持!


  • 上一条:
    vs2010出现error MSB8008的解决方法
    下一条:
    RegExp对象的方法和属性
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 近期文章
    • 在go语言中实现字符串可逆性压缩及解压缩功能(0个评论)
    • 使用go + gin + jwt + qrcode实现网站生成登录二维码在app中扫码登录功能(0个评论)
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-07
    • 2017-08
    • 2017-09
    • 2018-01
    • 2018-07
    • 2018-08
    • 2018-09
    • 2018-12
    • 2019-01
    • 2019-02
    • 2019-03
    • 2019-04
    • 2019-05
    • 2019-06
    • 2019-07
    • 2019-08
    • 2019-09
    • 2019-10
    • 2019-11
    • 2019-12
    • 2020-01
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2020-10
    • 2020-11
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-04
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-12
    • 2024-02
    • 2024-04
    • 2024-05
    • 2024-06
    • 2025-02
    • 2025-07
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客