基于cookie使用过滤器实现客户每次访问自登陆一次

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

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

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

1.cookies

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

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

  • 保存cookies

1

2

3

4

5

6

7

8

9

10

11

12

13

14

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,导致删除不了


1

2

3

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类进行注册,并设置它所能拦截的资源


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

<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>

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

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.结合上面提供知识,下面为整体代码展示,如发现不对地方,欢迎大家指出


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

@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";

    }

}

到此,该功能示例讲解全部完成,如有不对的地方,欢迎大家在评论区指出。

http://www.cnblogs.com/zhaixiajiao/p/6895284.html

 

时间: 2024-10-07 10:16:24

基于cookie使用过滤器实现客户每次访问自登陆一次的相关文章

基于COOKIE的点击流数据仓库构建思路(一)

网站数据是企业数据的重要组成部分,在大型企业中,数据通常以关系型数据仓库进行存储.当然,部分企业也在向基于Hadoop等开源框架的分布式非关系型数据仓库结构转变,但这仍只是少数.大部分公司仍然是关系型数据仓库(RDB)居于主流.接下来的三篇文章会介绍三种基于Cookie的点击流数据仓库构建思路.本篇是第一篇,基于Adobe Sitecatalyst底层数据的数据仓库作为原型. 在用该工具的人都知道,在Marketing Cloud中有个DataWarehouse的工具,该工具的作用类似于Exce

JS基于cookie实现来宾统计记录访客信息的方法_javascript技巧

本文实例讲述了JS基于cookie实现来宾统计记录访客信息的方法.分享给大家供大家参考.具体如下: 这里使用JavaScript记录访客的来宾信息,记录是第几次来访,显示的信息有:您的名字;您浏览该网页的次数;您上次浏览网页的时间.可以更改姓名. 运行效果如下图所示: 具体代码如下: <html> <head> <title>记录客户信息</title> <script language="JavaScript"> <!

PHP基于cookie与session统计网站访问量并输出显示的方法_php技巧

本文实例讲述了PHP基于cookie与session统计网站访问量并输出显示的方法.分享给大家供大家参考,具体如下: <?php $f_open = fopen("count.txt","r+"); //打开指定的文件 $count = fgets($f_open); //读取文件中的数据 if(empty($_COOKIE['cookie_name'])){ //判断COOKIE的是否存在 setcookie("cookie_name",

js基于cookie记录来宾姓名的方法_javascript技巧

本文实例讲述了js基于cookie记录来宾姓名的方法.分享给大家供大家参考,具体如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <

《响应式Web设计:HTML5和CSS3实践指南》——1.3节基于cookie及JavaScript的响应式图像

1.3 基于cookie及JavaScript的响应式图像使用复杂的服务器端逻辑也能实现响应式图像.有时因为一些特殊的需求,开发者往往不能够采取最简单的方法来实现特定的目标.之前提到的基于宽度百分比的方法依赖于客户端来实现对于大图像文件的缩放.而本方法则是在服务器端依据客户的请求,返回恰当大小的图像文件.如果你正为网页加载过慢导致的网站性能问题而烦恼,也许该方法能够给不堪重负的服务器负载和网络带宽带来一些改进. 1.3.1 准备工作本条目所涉及的方法都需要在服务器端实现相应的功能.首先,服务器端

webapi接口访问验证是否登陆的解决方案!每次访问接口都需要验证用户是否登陆!

问题描述 webapi接口访问验证是否登陆的解决方案!每次访问接口都需要验证用户是否登陆! webapi接口访问验证是否登陆的解决方案!每次访问接口都需要验证用户是否登陆! 解决方案 不明白,可以说的明白点么 解决方案二: 就是用户在每次访问接口的时候要在接口中验证是否登陆过,登陆过就可以访问,没有登录就返回没有登录的信息! 解决方案三: 通过session ID等作为参数 解决方案四: 谁有设计思路啊,完全不知道怎么处理了! 解决方案五: 用wenbservice,不是有sessioniD吗?

js基于cookie方式记住返回页面用法示例_javascript技巧

本文实例讲述了js基于cookie方式记住返回页面的用法.分享给大家供大家参考,具体如下: 首先明确以下概念 ①. 同名的 cookie,不同的 domain 或不同的 path,属不同的 cookie: 同名的 cookie,相同的 domain 且相同的 path,不同的 expires,属同一个 cookie. ②. 不加过期时间的cookie在浏览器关闭后失效 ③ 二级域名cookie可以生效,通过指定domain 于是在js端 document.cookie="back_url=&qu

JavaScript实现基于Cookie的存储类实例_javascript技巧

本文实例讲述了JavaScript实现基于Cookie的存储类.分享给大家供大家参考.具体分析如下: 通过这个JS类,你可以象使用session一样使用cookie,非常简单了! /* * CookieStorage.js * 本类实现像localStorage和sessionStorage一样的存储API * 不同的是,它是基于HTTP Cookies实现的. */ function CookieStorage(maxage, path) { // 两个参数分别代表储存有效期和作用域 // 获

如何知道客户能否访问某网站

问题描述 有什么办法可以知道客户能否访问我的网站现在只知道客户端的IP有没有办法知道此IP能否访问这个DNS因为有客户反映能访问这台机器的一个网站但同一台机器的另外一个网站就无法访问 解决方案 解决方案二:可以ping一下,程序中是可以通过ping去判断的解决方案三:查看IISlog解决方案四:客户得到什么错误.我觉得是不是telnet好点?解决方案五:IISLOG应该是不行,因为他都无法解析到这个域名,怎么会访问到IIS呢?ping的话,好象也有点问题,比如一个网站,我是无法访问的但居然pin