springmvc+cookie+session实现的简单自动登录

学习了一天左右的cookie和session,用自己的理解写了个简单的登录

学习过程中遇到的问题:

  1. cookie中的JSESSIONID,暂时不懂作用
  2. 前端用ajax请求成功后使用location.replace方法跳转界面,能够成功跳转却无法阻止浏览器后退按钮(未解决)
  3. 使用cookie登录但没有session,导致被拦截器拦截登录请求(已解决)
  4. 用户登录成功后使用浏览器后退按钮或url回到登录页面导致重复登录(目前只能做到使用拦截器阻止用户通过url进入登录页面)
  5. 暂时还没想起其它,想到后在补充
  6. 不知道这样写会不会有什么问题,错误或不足之处还请指正。

下面是代码:

前端ajax提交登录表单

function login(){
    var username = $("#username").val();
    var password = $("#password").val();
    var autologin = $("#autologin").is(':checked');
    $.ajax({
        type:"post",
        url:"/tomain",
        data: {
            username: username,
            password: password,
            autologin: autologin
        },
        success:function (page) {
            location.href="http://localhost:8080/"+page;
        }
    });
}

提交表单的方法

/*
    * 三个值分别表示账号、密码、是否勾选记住密码
    */
    @RequestMapping("/tomain")
    @ResponseBody
    public String tomain(
            @RequestParam("username") String username,
            @RequestParam("password") String password,
            @RequestParam("autologin") boolean autologin,
            HttpServletRequest request,
            HttpServletResponse response){
        Cookie[] cookies = request.getCookies();
        //cookies为空表示上次登录时没有选择自动登录或第一次登录
        if (cookies == null){
            //如果账号密码匹配
            if (username != null && !username.equals("") && password.equals("123456")){
                //取到session值,没有则创建
                HttpSession session = request.getSession();
                session.setAttribute("logOn",username);
                //设置最大存活时间,单位为秒
                session.setMaxInactiveInterval(60*10);
                //将账号密码存入cookie,在实际开发中账号密码需要先进行加密
                Cookie cookie = new Cookie("autoLogin",username+"#"+password);
                /*
                * 如果用户勾选了自动登录
                * 就给cookie一个存活时间
                * 这样就不会随着浏览器的关闭而清除cookie
                * 否则就不设置,这样当用户关闭浏览器时就会清除cookie
                * 下次登录仍然需要输入账号密码
                */
                if (autologin){
                    System.out.println("自动登录,一个月后过期");
                    //设置最大年龄,即为cookie存活时间,单位为秒
                    cookie.setMaxAge(60*60*24*30);
                    cookie.setPath("/");
                }
                //把cookie发送给客户端,由客户端保存
                response.addCookie(cookie);
                System.out.println("登录成功");
                return "main";
            }else {
                System.out.println("账号或密码错误");
                return "login";
            }
        }else {
            //有cookie则验证cookie中是否包含自动登录的账号密码
            for (Cookie cookie : cookies) {
                /*
                * 考虑到cookie会保存一个月,而session只存在十分钟
                * 为了防止用户携带cookie登录时被拦截器拦截
                * 验证用户的登录session是否还在,不在则创建一个新的
                */
                if(cookie.getName().equals("autoLogin")){
                    HttpSession session = request.getSession();
                    if(session.getAttribute("logOn") == null){
                        session.setAttribute("logOn",username);
                        session.setMaxInactiveInterval(60*10);
                    }
                    return "main";
                }
            }
            System.out.println("没有选择自动登录");
            return "login";
        }
    }

退出登录

@RequestMapping("/logout")
    public String logout(HttpServletRequest request,HttpServletResponse response){
        //退出登录时去掉登录session和自动登录cookie
        request.getSession().removeAttribute("logOn");
        Cookie autocookie = new Cookie("autoLogin",null);
        autocookie.setMaxAge(0);
        autocookie.setPath("/");
        response.addCookie(autocookie);
        //暂时不懂JSESSIONID的作用,退出登录时将它也处理掉
        Cookie sessionid = new Cookie("JSESSIONID",null);
        sessionid.setMaxAge(0);
        sessionid.setPath("/");
        response.addCookie(sessionid);
        return "redirect:/login";
    }

两个拦截器:
MainInterCeptor

public class MainInterCeptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        /*
        * 判断cookie和session是否都没有
        * 都没有视为未登录,拒绝进入主页面
        * 这里只能用&&使用||会导致页面在这里和LoginInterCeptor之间来回重定向
        * 导致浏览器抛出localhost多次重定向从而拒绝服务
        * 这只是给暂时的解决办法,更好的办法还没想到
        */
        Cookie[] cookies = request.getCookies();
        if(request.getSession().getAttribute("logOn") == null && cookies == null){
            System.out.println("拦截请求");
            response.sendRedirect("/login");
            return false;
        }else {
            return true;
        }
    }
}

LoginInterCeptor

public class LoginInterCeptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Cookie[] cookies = request.getCookies();
        //拦截登录页,当cookie有值时说明已经选择了自动登录或者已经登录,不允许进入登录页
        if (cookies == null){
            System.out.println("拦截器执行了,允许进入登录页");
            return true;
        }else {
            System.out.println("拦截器执行了,拒绝进入登录页");
            response.sendRedirect("/main");
            return false;
        }
    }
}

mvc扩展配置

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //添加MainInterCeptor拦截器
        registry.addInterceptor(new MainInterCeptor())
                .addPathPatterns("/main")
                .excludePathPatterns("/","/css/**","/fonts/**","/img/**","/js/**");
        //添加LoginInterCeptor拦截器
        registry.addInterceptor(new LoginInterCeptor())
                .addPathPatterns("/login")
                .excludePathPatterns("/","/css/**","/fonts/**","/img/**","/js/**");
    }
}

开始找到一个能够阻止浏览器返回按钮的方法,经过几次代码修改之后失效了(这个方法没改,改的是自己写的代码),这里也放上来

window.location.hash="no-back";
window.location.hash="Again-No-back-button";
window.onhashchange=function(){
    window.location.hash="no-back";
}

经过几次的修改,已经把这一天对cookie和session的理解都用上了,目前只能做到这里,下次再深入探究吧

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值