发表于: 2017-11-04 22:17:13

1 815


今天完成的事情

编写拦截器对请求中的Cookie进行验证

当用户第一次登陆时,在控制器中为用户生成Cookie,便于之后的免登陆操作:

@RequestMapping("login1")
public String login2(HttpServletRequest request, HttpServletResponse response) throws IOException{
//获取提交的用户名 name
   String name = request.getParameter("name");
   //根据name取出数据库中的用户id
   int user_id =userService.get(name).getUser_id();
   //转字符串
   String user_id_s=String.valueOf(user_id);
   //取得登陆时间
   long login_at=System.currentTimeMillis();
   //long类型时间转字符串
   String login_at_s=String.valueOf(login_at);
   //组合为token
   String token2=user_id_s+"."+login_at_s;
   //加密
   String token= DESEncryptTools.encrypt(token2);
   //token放入Cookie
   Cookie cookie1 = new Cookie("token",token);
   cookie1.setMaxAge(30*60);
   //路径
   cookie1.setPath("/");
   response.addCookie(cookie1);
   return "redirect:/home";
}

基本逻辑是:先不考虑各种特殊情况,在理想情况下,用户提交用户名和密码,在控制器中通过 request.getParameter("name")获取到用户名,根据用户名从数据库获取到对应的用户id,将id转换为String类型,再获取到登陆的时间,为long类型,同样转换为String类型,将两个字符串组合再一起,中间隔一个 " . "   组成一个字符串,通过  DESEncryptTools.encrypt(token2)  进行加密,这个方法是自定义的主要利用DES进行加密,生成token令牌,然后创建一个Cookie,设置name为token,value为刚才生成的token令牌。设置有效期为30分钟。设置访问路径为 "/ "  ,表示所有访问都会提交此token。通过 response.addCookie(cookie1) 加入到响应中,发送到客户端,最后重定向到首页。

 编写拦截器,首先要写一个类,需要实现springMVC中的接口HandlerInterceptor,需要实现其中的三个方法:

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception{
if (!isAllow(request))
response.sendRedirect("/login.jsp");
   return true;
}

preHandle方法是进行拦截用的,该方法再Controller处理之前进行调用,当返回值为false时整个请求就结束了,其中的isAllow()方法是自定义的,用于判断请求是否通过。

public void postHandle(HttpServletRequest request, HttpServletResponse response,Object obj, ModelAndView modelAndView)
throws Exception{
}

postHandle()方法在preHandle方法返回true的时候才会执行,在Controller执行之后执行,会在视图进行渲染之前执行,通常用来对视图进行操作,在此任务中用不到,所以方法体为空。

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,Exception ex)
   throws Exception{

}

afterCompletion()方法在完成整个请求之后执行,通常用于清理资源,这里也设置为空了。

isAllow()方法用于判断Cookie是否有效

private boolean isAllow(HttpServletRequest request){
//获取请求中的所有的Cookie
   Cookie[] cookies=request.getCookies();
   for (Cookie cookie:cookies) {
//判断Cookie是否有效
       if (cookie.getName().equals("token")){
          if (isTrue(cookie)){
             return true;
           }
          else{
              return false;
            }
          }
     }
        return false;
}

通过request.getCookies()获取所有Cookie,放入Cookie数组cookies中,对所有Cookie进行遍历,找到其中name为token的Cookie并调用isTrue()方法来进行判断,若符合要求,返回true,否则返回false,isTrue()方法也是自定义的。

isTrue()方法用于对Cookie进行解密操作,并验证token令牌中的信息是否符合要求

private boolean isTrue(Cookie cookie){
String value = DESEncryptTools.decrypt(cookie.getValue());
   int index = value.indexOf(".");
   String id_s = value.substring(0,index);
   //Stringint
   int id = Integer.parseInt(id_s);
   String time = value.substring(index+1);
   //Stringlong
   long login_time = Long.parseLong(time);
   //判断数据库中是否有此用户
   if (null!=userService.getById(id)){
   //取得当前时间
       long now=System.currentTimeMillis();
      long period=(now-login_time)/1000;
       //判断有效时间
       if (period<(30*60)){
         return true;
         }
    }else{
       return false;
    }
    return false;
}

先进行解密,获得字符串value,查找字符串中的  " . "  的位置,用substring()方法取出  " . "

之前的字符, 用同样的方法取出 " . "  之后的字符,前面的字符是用户的id,先转换为int类型,然后通过id判断在数据库中是否有此用户,没有的话,返回false,后面的字符为登陆时间,先转换为long类型,当验证了数据库中有此用户时,取得当前时间,用后者减去前者并除以1000,获得相差时间,单位为秒,判断此时间差是否在所设定的有效期内,是的话就返回true。

还需要再springMVC配置文件中配置:

<mvc:interceptors>
   <bean class="com.jnshu.util.LoginInterceptor"/>
</mvc:interceptors>

之后,请求就会先通过拦截器进行验证了。


明天的计划

完成任务五


遇到的问题


收获

了解了拦截器的作用及配置。



返回列表 返回列表
评论

    分享到