发表于: 2017-07-03 21:01:25

1 1265


今天完成的事情:

login.jsp

<%@page import="java.security.SecureRandom"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
<%
   String path = request.getContextPath();
   String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
   <base href="<%=basePath%>">
   <title>SpringMVC Cookie Demo</title>
   <%
       SecureRandom random = new SecureRandom();
       random.setSeed(8738);
       double _csrf = random.nextDouble();
       session.setAttribute("_csrf", _csrf);
   %>
</head>
<body>
<div align="center">
   <h2>SpringMVC Cookie Demo</h2>
   <form action="check.html" method="post">
       <table>
           <tr>
               <td>用户名:</td>
               <td><input type="text" name="username" /></td>
           </tr>
           <tr>
               <td>密码:</td>
               <td><input type="password" name="password" /></td>
           </tr>
           <tr>
               <td><input name="remember-me" type="checkbox">30天内自动登录</input></td>
           </tr>
           <tr>
               <td colspan="2" align="center"><input type="submit" value="登录" />
                   <input type="reset" value="重置" /></td>
           </tr>
       </table>
       <input type="hidden" name="_csrf" value="<%=_csrf %>" />
   </form>

</div>
</body>
</html>

拦截器

package me.wyc.interceptor;

import java.util.Calendar;
import java.util.Date;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import cn.zifangsky.manager.UserManager;
import cn.zifangsky.manager.impl.PersistentLoginsManagerImpl;
import cn.zifangsky.model.PersistentLogins;
import cn.zifangsky.model.User;
import cn.zifangsky.utils.CookieConstantTable;
import cn.zifangsky.utils.CookieUtils;
import cn.zifangsky.utils.EncryptionUtil;

public class UserInterceptor extends HandlerInterceptorAdapter {
@Resource(name = "persistentLoginsManagerImpl")
private PersistentLoginsManagerImpl persistentLoginsManagerImpl;
   @Resource(name = "userManagerImpl")
private UserManager userManager;

   /**
    * 用于处理自动登录
    */
   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
HttpSession session = request.getSession();
       User user = (User) session.getAttribute("user");

       // 已登录
       if (user != null) {
return true;
       } else {
// 从cookie中取值
           Cookie rememberme = CookieUtils.getCookie(request, CookieConstantTable.RememberMe);
           if (rememberme != null) {
String cookieValue = EncryptionUtil.base64Decode(rememberme.getValue());

               String[] cValues = cookieValue.split(":");
               if (cValues.length == 2) {
String usernameByCookie = cValues[0]; // 获取用户名
                   String uuidByCookie = cValues[1]; // 获取UUID值
                   // 到数据库中查询自动登录记录
                   PersistentLogins pLogins = persistentLoginsManagerImpl.selectByUsernameAndSeries(usernameByCookie,
                           uuidByCookie);
                   if (pLogins != null) {
String savedToken = pLogins.getToken(); // 数据库中保存的密文

                       // 获取有效时间
                       Date savedValidtime = pLogins.getValidtime();
                       Date currentTime = new Date();

                       // 如果还在cookie有效期之内,继续判断是否可以自动登录
                       if (currentTime.before(savedValidtime)) {
User u = userManager.selectByName(usernameByCookie);
                           if (u != null) {
Calendar calendar = Calendar.getInstance();
                               calendar.setTime(pLogins.getValidtime());
                               // 精确到分的时间字符串
                               String timeString = calendar.get(Calendar.YEAR) + "-" + calendar.get(Calendar.MONTH)
+ "-" + calendar.get(Calendar.DAY_OF_MONTH) + "-"
                                       + calendar.get(Calendar.HOUR_OF_DAY) + "-" + calendar.get(Calendar.MINUTE);
                               // 为了校验而生成的密文
                               String newToken = EncryptionUtil.sha256Hex(u.getName() + "_" + u.getPassword() + "_"
                                       + timeString + "_" + CookieConstantTable.salt);

                               // 校验sha256加密的值,如果不一样则表示用户部分信息已被修改,需要重新登录
                               if (savedToken.equals(newToken)) {
/**
                                    * 为了提高安全性,每次登录之后都更新自动登录的cookie值
                                    */
                                   // 更新cookie值
                                   String uuidNewString = UUID.randomUUID().toString();
                                   String newCookieValue = EncryptionUtil
.base64Encode(u.getName() + ":" + uuidNewString);
                                   CookieUtils.editCookie(request, response, CookieConstantTable.RememberMe,
                                           newCookieValue, null);

                                   // 更新数据库
                                   pLogins.setSeries(uuidNewString);
                                   persistentLoginsManagerImpl.updateByPrimaryKeySelective(pLogins);

                                   /**
                                    * 将用户加到session中,不退出浏览器时就只需判断session即可
                                    */
                                   session.setAttribute("user", u);

                                   return true;  //校验成功,此次拦截操作完成
                               } else { // 用户部分信息被修改,删除cookie并清空数据库中的记录
                                   CookieUtils.delCookie(response, rememberme);
                                   persistentLoginsManagerImpl.deleteByPrimaryKey(pLogins.getId());
                               }
}
} else { // 超过保存的有效期,删除cookie并清空数据库中的记录
                           CookieUtils.delCookie(response, rememberme);
                           persistentLoginsManagerImpl.deleteByPrimaryKey(pLogins.getId());
                       }
}
}
}
//将来源地址存放在session中,登录成功之后跳回原地址
           String callback = request.getRequestURL().toString();
           session.setAttribute("callback", callback);
           response.sendRedirect(
request.getContextPath() + "/login.html?callback=" + callback);
           return false;
       }
}

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

super.afterCompletion(request, response, handler, ex);
   }

明天计划的事情:做完任务5

遇到的问题:没跑具体问题歇会再说

收获:这几天走远了


返回列表 返回列表
评论

    分享到