基于Cookie使用过滤器实现客户访问登录功能的详解

互联网 17-6-15
这篇文章主要介绍了基于Cookie使用过滤器实现客户每次访问只登录一次,需要的朋友可以参考下

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

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

本文代码示例框架为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);// 删除密码cookie  response.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 {              // 登陆成功保存客户信息到session              session.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使用过滤器实现客户访问登录功能的详解的详细内容,更多内容请关注技术你好其它相关文章!

来源链接:
免责声明:
1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险
2.本文版权归属原作所有,仅代表作者本人观点,不代表本站的观点或立场
上一篇:php获取远程图片并下载保存到本地的方法分析 下一篇:过滤器详解的10篇内容推荐

相关资讯