业务功能开发-登录(四)
解密登录cookie:
用户在登录成功之后,每次访问系统都会在当前请求中获取cookie并解密cookie,获取登录用户ID和登录时间,用户id用来获取当前的用户,登录时间用来验证空闲超时,类似session的空闲超时,用于登录cookie的解密和登录空闲的超时处理都在AuthInterceptor的getCurrentUser方法中。
/**
* 获取当前登录用户
* @param request
* @param response
* @param userAgentVali 是否验证 User-Agent
* @return
*/
public static User getCurrentUser(HttpServletRequest request, HttpServletResponse response, boolean userAgentVali) {
String loginCookie = ToolWeb.getCookieValueByName(request, ConstantWebContext.cookie_authmark);
if (null != loginCookie && !loginCookie.equals("")) {
// 1.解密认证数据
String data = ToolIDEA.decrypt(loginCookie);
if(null == data || data.isEmpty()){
ToolWeb.addCookie(response, "", "/", true, ConstantWebContext.cookie_authmark, null, 0);
return null;
}
String[] datas = data.split(".#."); //arr[0]:时间戳,arr[1]:USERID,arr[2]:USER_IP, arr[3]:USER_AGENT
// 2. 分解认证数据
long loginDateTimes;
String userIds = null;
String ips = null;
String userAgent = null;
boolean autoLogin = false;
try {
loginDateTimes = Long.parseLong(datas[0]); // 时间戳
userIds = datas[1]; // 用户id
ips = datas[2]; // ip地址
userAgent = datas[3]; // USER_AGENT
autoLogin = Boolean.valueOf(datas[4]); // 是否自动登录
} catch (Exception e) {
ToolWeb.addCookie(response, "", "/", true, ConstantWebContext.cookie_authmark, null, 0);
return null;
}
// 3.用户当前数据
String newIp = ToolWeb.getIpAddr(request);
String newUserAgent = request.getHeader("User-Agent");
Date start = ToolDateTime.getDate();
start.setTime(loginDateTimes); // 用户自动登录开始时间
int day = ToolDateTime.getDateDaySpace(start, ToolDateTime.getDate()); // 已经登录多少天
int maxAge = PropKit.getInt(ConstantInit.config_maxAge_key);
// 4. 验证数据有效性
if (ips.equals(newIp) && (userAgentVali ? userAgent.equals(newUserAgent) : true) && day <= maxAge) {
// 如果不记住密码,单次登陆有效时间验证
if(!autoLogin){
int minute = ToolDateTime.getDateMinuteSpace(start, new Date());
int session = PropKit.getInt(ConstantInit.config_session_key);
if(minute > session){
return null;
}else{
// 重新生成认证cookie,目的是更新时间戳
long date = ToolDateTime.getDateByTime();
StringBuilder token = new StringBuilder();// 时间戳.#.USERID.#.USER_IP.#.USER_AGENT.#.autoLogin
token.append(date).append(".#.").append(userIds).append(".#.").append(ips).append(".#.").append(userAgent).append(".#.").append(autoLogin);
String authmark = ToolIDEA.encrypt(token.toString());
// 添加到Cookie
int maxAgeTemp = -1; // 设置cookie有效时间
ToolWeb.addCookie(response, "", "/", true, ConstantWebContext.cookie_authmark, authmark, maxAgeTemp);
}
}
// 返回用户数据
Object userObj = User.dao.cacheGet(userIds);
if (null != userObj) {
User user = (User) userObj;
return user;
}
}
}
return null;
}
解密数据的流程很简单,就是获取cookie密文后使用密钥解密即可,然后就是分解数据,在验证数据有效性的时候,增加了当前操作时间和登录时间的对比,用来验证操作空间间隔时间是否超时,如果超时则返回null,AuthInterceptor会调整到登陆页,如果没有超时,验证通过,并且同时更新登录时间为当前访问时间