发表于: 2017-06-01 09:03:57
1 1213
今天完成的事情:
1、使用DES对用户ID和登录时间加密,生成Token,放入Cookie中,拦截器里通过Cookie中判断Token的有效性来判断用户是否登录。
UserController:
@RequestMapping(value = "/login", method = RequestMethod.POST)
public ModelAndView login(@RequestParam("username") String username,
@RequestParam("password")String password,
@RequestParam(value = "remember-me", required = false)boolean rememberme,
HttpServletRequest request,
HttpServletResponse response, RedirectAttributes redirectAttributes){
HttpSession session = request.getSession();
User user = new User();
user.setUsername(username);
user.setPassword(password);
User result = userService.SelectByUser(user);
if (result == null){
return new ModelAndView("login");
}
// 1, session ; 2, cookie
long currentTimeMillis = System.currentTimeMillis();
String encrypt = DesUtils.encrypt(username + "_" + currentTimeMillis, CookieConstantTable.salt);
CookieUtils.addCookie(response,CookieConstantTable.COOKIE_NAME ,encrypt,"/");
session.setAttribute("user", result); // 登录成功之后加入session中
ModelAndView modelAndView = new ModelAndView("redirect:/main/feature");
modelAndView.addObject("user",user);
return modelAndView;
}
UserInterceptor:
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
HttpSession session = request.getSession();
User user = (User) session.getAttribute("user");
// 已登录
if (null != user) {
return true;
}
//
String cookieValue = CookieUtils.getCookieValue(request, COOKIE_NAME);
if (cookieValue == null){
return true;
}
String decrypt = DesUtils.decrypt(cookieValue, CookieConstantTable.salt);
String[] cValues = decrypt.split("_");
if (cValues.length==2){
String username = cValues[0];
String lastLoginTime = cValues[1];
user.setUsername(username);
user.setLastlogintime(Long.parseLong(lastLoginTime));
User selectByUser = userService.SelectByUser(user);
if (null != selectByUser){
/**
* 将用户加到session中,不退出浏览器时就只需判断session即可
*/
session.setAttribute("user", user);
return true;
}
}
return false;
}
在拦截器中,通过用户名和登录时间查找该用户。
<select id="selectByUser" resultMap="BaseResultMap" parameterType="com.jn.bean.User" >
select
<include refid="Base_Column_List" />
from user
<where>
<if test="username != null">
username=#{username}
</if>
<if test="password != null">
AND password=#{password}
</if>
<if test="lastlogintime != null">
AND lastLoginTime=#{lastlogintime}
</if>
</where>
</select>
拦截器配置:
<mvc:interceptors>
<mvc:interceptor>
<!-- 对*/u/**的请求进行拦截 -->
<mvc:mapping path="*/u/**"/>
<bean class="com.jn.web.interceptor.UserInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
2、
明天计划的事情:
任务5总结。开始任务6。
遇到的问题:
1、要求用户必须登录才能访问的url统一增加前缀 /u/。
这个问题我还不能具体表达出来,我自己再想想。
收获:
1.什么是cookie?什么场景适用于cookie?
cookie一般情况下用于记录用户的登录状态,比如userid,千万不要记录密码,由于cookie是存储在客户端的,所以cookie很容易被人劫持修改。
比如登录成功后在客户端写入cookie,名为userId,值为1。该用户下次访问时,服务器端读取cookie userId的值,如果userId在数据库用户表中可以找到,则证明当前用户userId为1且让该用户合法登录,显然这样是不可行的。
因为如果用户自行修改userId为2或者其它用户的userId,那么服务器就认为当前合法登录的用户userId为2,这样用户就不需要知道userid为2的密码就合法登录了。
修改cookie可以通过直接修改浏览器cookie文件或者通过JavaScript修改cookie值达到欺骗服务器的目的,所以需要对存储在客户端的cookie要进行加密。
2.MD5加密
通过MD5算法对userid进行加密然后存储在客户端cookie中,由于MD5是不可逆的,所以服务器端在收到cookie(‘userid’)的时候也不可以解密,那么服务器应该在用户数据表中添加一个字段专门存储MD5加密后的userid,然后通过SQL查询到userid。
虽然MD5是不可逆的,但是MD5还是可以暴力破解的,尤其是对于userid这种纯数字的,比如userid为12345,MD5加密后的值为827CCB0EEA8A706C4C34A16891F84E7B,我们把加密后的值放到http://www.cmd5.com/中解密看看,不到2秒结果12345就出来了。
如果某个不怀好意的人知道了你的userid只是经过了一次MD5加密,那么用户随便对一个已经存在的userId进行MD5加密,然后伪造cookie(‘userid’),此时服务器会认为用户为合法用户了,获取了其它用户的权限。那么有个办法是对userid进行两次MD5加密或者加一个复杂的key,因为越复杂MD5暴力破解就越慢,如果暴力破解需要2万年那就没有任何意义了。
评论