package com.app.mvc.acl.util;
import com.app.mvc.acl.domain.SysUser;
import com.app.mvc.acl.dto.CookieUser;
import com.app.mvc.acl.dto.LoginUser;
import com.app.mvc.acl.enums.Status;
import com.app.mvc.acl.service.SysUserService;
import com.app.mvc.beans.JsonMapper;
import com.app.mvc.common.SpringHelper;
import com.app.mvc.config.GlobalConfig;
import com.app.mvc.config.GlobalConfigKey;
import com.app.mvc.util.Base64Util;
import com.app.mvc.util.CookieUtil;
import com.app.mvc.util.IpUtil;
import com.app.mvc.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by jimin on 16/2/10.
*/
@Slf4j
public class LoginUtil {
private final static String DEFAULT = "@6CFB18E2#iLpYs8Tb";
private final static String DEFAULT_USER_COOKIE = "_U";
private final static String USER_NAME_COOKIE = "_UN";
private final static String USER_MAIL_COOKIE = "_UM";
private final static String PREFIX = "9c0Mk$%S9mD&Yu";
private final static String SUFFIX = "uIml&8k#pI92*Qr";
private final static int DEFAULT_EXPIRE_SECONDS = 1800;
public static void saveUserToCookie(HttpServletRequest request, HttpServletResponse response, SysUser sysUser) {
if (sysUser == null) {
return;
}
try {
String userCookie = generateUserCookie(request, sysUser);
CookieUtil.setCookie(request, response, getUserNameCookie(), userCookie, getDefaultExpireSeconds());
CookieUtil.setCookie(request, response, USER_NAME_COOKIE, sysUser.getUsername(), getDefaultExpireSeconds());
CookieUtil.setCookie(request, response, USER_MAIL_COOKIE, sysUser.getMail(), getDefaultExpireSeconds());
} catch (Throwable t) {
log.error("user login succeed, save cookie exception, user: {}", JsonMapper.obj2String(sysUser), t);
}
}
public static LoginUser getUserFromCookie(HttpServletRequest request, HttpServletResponse response) {
String userCookie = "";
try {
Cookie cookie = CookieUtil.getCookie(request, getUserNameCookie());
if (cookie == null || StringUtil.isEmpty(cookie.getValue())) {
return LoginUser.fail("未获取到登录的用户信息,请登录");
}
userCookie = cookie.getValue();
if (!userCookie.startsWith(PREFIX) || !userCookie.endsWith(SUFFIX)) {
return LoginUser.fail("用户信息校验不通过,请登录");
}
// 先去掉前缀和后缀, 再反转
userCookie = StringUtils.reverse(userCookie.replace(PREFIX, "").replace(SUFFIX, ""));
// 使用=替换默认的字符串, base64解密
String decodeBase64 = Base64Util.decodeStr(userCookie.replaceAll(DEFAULT, "="));
// json串反转为CookieUser对象
CookieUser cookieUser = JsonMapper.string2Obj(decodeBase64, CookieUser.class);
if (cookieUser == null) {
return LoginUser.fail("获取登录的用户信息出现问题,请重新登录");
}
// 校验是否过期
long during = System.currentTimeMillis() - cookieUser.getLastLogin();
if (during / 1000 > getDefaultExpireSeconds()) {
return LoginUser.fail("当前用户登录信息已过期,请重新登录");
}
SysUserService sysUserService = SpringHelper.popBean(SysUserService.class);
SysUser sysUser = sysUserService.findById(cookieUser.getUserId());
if (sysUser == null) {
return LoginUser.fail("当前用户未在系统中查询到,请重新登录");
}
if (sysUser.getStatus() != Status.AVAILABLE.getCode()) {
return LoginUser.fail("当前用户状态无效,请联系管理员");
}
if (!sysUser.getMail().equals(cookieUser.getUsername())) {
return LoginUser.fail("当前用户名和系统中记录的用户名不一致,请重新登录");
}
String ip = IpUtil.getRemoteIp(request);
String mac = IpUtil.getMACAddress(ip).replaceAll("-", "");
if (!mac.equals(cookieUser.getMac())) {
log.error("检测出用户mac地址和cookie中的记录的mac不一致,可能是在拼cookie, username:{}", sysUser.getUsername());
return LoginUser.fail("当前用户登录信息和登录时的设备不一致,请重新登录");
}
if (!ip.equals(cookieUser.getIp())) {
log.error("检测出用户ip地址和cookie中的记录的ip不一致,可能是在拼cookie, username:{}", sysUser.getUsername());
}
saveUserToCookie(request, response, sysUser);
return LoginUser.success(sysUser);
} catch (Throwable t) {
log.error("handle user cookie error, cookie: {}", userCookie, t);
return LoginUser.fail("处理用户信息出错,请重新登录");
}
}
public static void logout(HttpServletRequest request, HttpServletResponse response) {
CookieUtil.setCookie(request, response, getUserNameCookie(), "", 0);
}
private static int getDefaultExpireSeconds() {
return GlobalConfig.getIntValue(GlobalConfigKey.COOKIE_EXPIRE_SECONDS, DEFAULT_EXPIRE_SECONDS);
}
public static String getUserNameCookie() {
return GlobalConfig.getStringValue(GlobalConfigKey.COOKIE_USER_FLAG, DEFAULT_USER_COOKIE);
}
private static String generateUserCookie(HttpServletRequest request, SysUser sysUser) {
String ip = IpUtil.getRemoteIp(request);
String mac = IpUtil.getMACAddress(ip).replaceAll("-", "");
// 设置cookieUser类
CookieUser cookieUser = CookieUser.builder().userId(sysUser.getId()).username(sysUser.getMail()).ip(ip).mac(mac).lastLogin(System.currentTimeMillis())
.build();
// 得到cookieUser类对应的json串,base64加密后,并将=使用默认字符替换
String encodeBase = Base64Util.encode(JsonMapper.obj2String(cookieUser).getBytes()).replaceAll("=", DEFAULT);
// 反转
encodeBase = StringUtils.reverse(encodeBase);
// 补充上前缀和后缀
encodeBase = PREFIX + encodeBase + SUFFIX;
return encodeBase;
}
}