发表于: 2017-11-04 22:17:13
1 816
今天完成的事情
编写拦截器对请求中的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);
//String转int
int id = Integer.parseInt(id_s);
String time = value.substring(index+1);
//String转long
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>
之后,请求就会先通过拦截器进行验证了。
明天的计划
完成任务五
遇到的问题
无
收获
了解了拦截器的作用及配置。
评论