全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

基于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使用过滤器实现客户每次访问只登录一次,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


# cookie  # 过滤器登录一次  # cookie、session和java过滤器结合实现登陆程序  # 自动登录  # 为空  # 不成功  # 您的  # 是在  # 不需要  # 一个月  # 欢迎大家  # 看一下  # 小编  # 跳转到  # 应用程序  # 下次  # 就会  # 在这  # 在此  # 两种  # 中有  # 您可以  # 它是 


相关文章: 企业网站制作公司网页,推荐几家专业的天津网站制作公司?  开源网站制作软件,开源网站什么意思?  兔展官网 在线制作,怎样制作微信请帖?  南平网站制作公司,2025年南平市事业单位报名时间?  西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?  学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?  如何在橙子建站上传落地页?操作指南详解  宠物网站制作html代码,有没有专门介绍宠物如何养的网站啊?  网站制作公司,橙子建站是合法的吗?  如何在云指建站中生成FTP站点?  C#如何使用XPathNavigator高效查询XML  如何快速生成橙子建站落地页链接?  seo网站制作优化,网站SEO优化步骤有哪些?  营销式网站制作方案,销售哪个网站招聘效果最好?  建站之星如何防范黑客攻击与数据泄露?  建站之星上传入口如何快速找到?  小建面朝正北,A点实际方位是否存在偏差?  c# 在ASP.NET Core中管理和取消后台任务  SAX解析器是什么,它与DOM在处理大型XML文件时有何不同?  如何正确选择百度移动适配建站域名?  哈尔滨网站建设策划,哈尔滨电工证查询网站?  如何用景安虚拟主机手机版绑定域名建站?  制作网站的软件下载免费,今日头条开宝箱老是需要下载怎么回事?  香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧  内网网站制作软件,内网的网站如何发布到外网?  深圳网站制作费用多少钱,读秀,深圳文献港这样的网站很多只提供网上试读,但有些人只要提供试读的文章就能全篇下载,这个是怎么弄的?  开封网站制作公司,网络用语开封是什么意思?  SQL查询语句优化的实用方法总结  重庆市网站制作公司,重庆招聘网站哪个好?  招商网站制作流程,网站招商广告语?  如何用已有域名快速搭建网站?  建站之家VIP精选网站模板与SEO优化教程整合指南  高防服务器:AI智能防御DDoS攻击与数据安全保障  如何在景安云服务器上绑定域名并配置虚拟主机?  网站制作壁纸教程视频,电脑壁纸网站?  如何使用Golang安装API文档生成工具_快速生成接口文档  头像制作网站在线制作软件,dw网页背景图像怎么设置?  ,有什么在线背英语单词效率比较高的网站?  ,如何利用word制作宣传手册?  如何用IIS7快速搭建并优化网站站点?  导航网站建站方案与优化指南:一站式高效搭建技巧解析  我的世界制作壁纸网站下载,手机怎么换我的世界壁纸?  高防服务器租用如何选择配置与防御等级?  制作网站怎么制作,*游戏网站怎么搭建?  建站之星logo尺寸如何设置最合适?  天河区网站制作公司,广州天河区如何办理身份证?需要什么资料有预约的网站吗?  移民网站制作流程,怎么看加拿大移民官网?  电商平台网站制作流程,电商网站如何制作?  香港服务器选型指南:免备案配置与高效建站方案解析  如何在建站之星网店版论坛获取技术支持? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。