Commit ebb9c509 authored by suntao's avatar suntao

修改登录

parent a09acac6
...@@ -34,11 +34,11 @@ public class LogController { ...@@ -34,11 +34,11 @@ public class LogController {
*/ */
@PostMapping("/login") @PostMapping("/login")
public Result<String> login(@RequestBody @Valid LoginFormModel loginFormModel) { public Result<String> login(@RequestBody @Valid LoginFormModel loginFormModel) {
Tuple<Boolean, ApplicationStatus> tuple = this.loginService.login(loginFormModel.getUsername(), loginFormModel.getPassword()); Tuple<ApplicationStatus, String> tuple = this.loginService.login(loginFormModel.getUsername(), loginFormModel.getPassword());
if (BooleanUtils.isTrue(tuple.getKey())) { if (ApplicationStatus.SUCCESS.equals(tuple.getKey())) {
return new Result<>(ApplicationStatus.SUCCESS, Application.getSession().getId()); return new Result<>(tuple.getKey(), tuple.getValue());
} else { } else {
return new Result<>(tuple.getValue(), ""); return new Result<>(tuple.getKey(), "");
} }
} }
......
...@@ -5,15 +5,15 @@ import cn.quantgroup.cashloanflowboss.api.user.dictionary.UserRank; ...@@ -5,15 +5,15 @@ import cn.quantgroup.cashloanflowboss.api.user.dictionary.UserRank;
import cn.quantgroup.cashloanflowboss.api.user.model.UserInfo; import cn.quantgroup.cashloanflowboss.api.user.model.UserInfo;
import lombok.Data; import lombok.Data;
import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
/** /**
* Created by WeiWei on 2019/7/26. * Created by WeiWei on 2019/7/26.
*/ */
@Data @Data
public class Principal { public class Principal implements Serializable {
/** /**
* 用户ID * 用户ID
...@@ -35,6 +35,11 @@ public class Principal { ...@@ -35,6 +35,11 @@ public class Principal {
*/ */
private List<Role> roles; private List<Role> roles;
/**
* 登录时间
*/
private Long loginTimeMillis;
/** /**
* 是否是超级管理员 * 是否是超级管理员
* *
......
...@@ -12,9 +12,8 @@ import java.util.Map; ...@@ -12,9 +12,8 @@ import java.util.Map;
* @author: suntao * @author: suntao
*/ */
public interface LoginService { public interface LoginService {
Tuple<Boolean, ApplicationStatus> login(String username, String password); Tuple<ApplicationStatus, String> login(String username, String password);
boolean logout(); boolean logout();
Map<String, Object> getConcurrentHashMapLoginInfo();
} }
...@@ -5,20 +5,27 @@ import cn.quantgroup.cashloanflowboss.api.user.dictionary.UserStatus; ...@@ -5,20 +5,27 @@ import cn.quantgroup.cashloanflowboss.api.user.dictionary.UserStatus;
import cn.quantgroup.cashloanflowboss.api.user.entity.User; import cn.quantgroup.cashloanflowboss.api.user.entity.User;
import cn.quantgroup.cashloanflowboss.api.user.model.UserInfo; import cn.quantgroup.cashloanflowboss.api.user.model.UserInfo;
import cn.quantgroup.cashloanflowboss.api.user.service.UserService; import cn.quantgroup.cashloanflowboss.api.user.service.UserService;
import cn.quantgroup.cashloanflowboss.core.Application;
import cn.quantgroup.cashloanflowboss.core.base.Tuple; import cn.quantgroup.cashloanflowboss.core.base.Tuple;
import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationDictionary; import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationDictionary;
import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationStatus; import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationStatus;
import cn.quantgroup.cashloanflowboss.utils.JSONTools; import cn.quantgroup.cashloanflowboss.utils.JSONTools;
import cn.quantgroup.cashloanflowboss.utils.MD5Tools; import cn.quantgroup.cashloanflowboss.utils.MD5Tools;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
/** /**
* Created by WeiWei on 2019/7/22. * Created by WeiWei on 2019/7/22.
...@@ -33,10 +40,11 @@ public class LoginServiceImpl implements LoginService { ...@@ -33,10 +40,11 @@ public class LoginServiceImpl implements LoginService {
@Autowired @Autowired
private HttpServletRequest request; private HttpServletRequest request;
/** @Resource(name = "redisTemplate")
* 用户为key,登陆信息(最后登陆时间) private ValueOperations<String, Principal> loginOperations;
*/
private ConcurrentHashMap<String, Object> loginInfo = new ConcurrentHashMap<>(8); // @Resource(name = "stringRedisTemplate")
// private StringRedisTemplate stringRedisTemplate;
/** /**
* 登入 * 登入
...@@ -46,20 +54,20 @@ public class LoginServiceImpl implements LoginService { ...@@ -46,20 +54,20 @@ public class LoginServiceImpl implements LoginService {
* @return * @return
*/ */
@Override @Override
public Tuple<Boolean, ApplicationStatus> login(String username, String password) { public Tuple<ApplicationStatus, String> login(String username, String password) {
User user = this.userService.getUser(username); User user = this.userService.getUser(username);
// 检查用户是否有效 // 检查用户是否有效
if (user == null) { if (user == null) {
log.info("用户不存在username=" + username); log.info("用户不存在username=" + username);
return new Tuple<>(Boolean.FALSE, ApplicationStatus.INVALID_USER); return new Tuple<>(ApplicationStatus.INVALID_USER, "");
} }
// 检查用户是否被禁用 // 检查用户是否被禁用
if (UserStatus.DISABLED.equals(user.getStatus())) { if (UserStatus.DISABLED.equals(user.getStatus())) {
log.info("用户已禁用username=" + username); log.info("用户已禁用username=" + username);
return new Tuple<>(Boolean.FALSE, ApplicationStatus.DISABLED_USER); return new Tuple<>(ApplicationStatus.DISABLED_USER, "");
} }
// 检查密码是否正确 // 检查密码是否正确
...@@ -67,7 +75,7 @@ public class LoginServiceImpl implements LoginService { ...@@ -67,7 +75,7 @@ public class LoginServiceImpl implements LoginService {
if (!user.getPassword().equalsIgnoreCase(passwordMd5)) { if (!user.getPassword().equalsIgnoreCase(passwordMd5)) {
log.info("用户名或密码错误username=" + username); log.info("用户名或密码错误username=" + username);
log.info("user.name:{},user.pwd:{},passwordMd5:{}", user.getUsername(), user.getPassword(), passwordMd5); log.info("user.name:{},user.pwd:{},passwordMd5:{}", user.getUsername(), user.getPassword(), passwordMd5);
return new Tuple<>(Boolean.FALSE, ApplicationStatus.USERNAME_OR_PASSWORD_ERROR); return new Tuple<>(ApplicationStatus.USERNAME_OR_PASSWORD_ERROR, "");
} }
// 创建Session // 创建Session
...@@ -84,19 +92,20 @@ public class LoginServiceImpl implements LoginService { ...@@ -84,19 +92,20 @@ public class LoginServiceImpl implements LoginService {
principal.setChannelId(user.getChannelId()); principal.setChannelId(user.getChannelId());
principal.setRank(user.getRank()); principal.setRank(user.getRank());
principal.setRoles(user.getRoles()); principal.setRoles(user.getRoles());
long currentTimeMillis = System.currentTimeMillis(); long currentTimeMillis = System.currentTimeMillis();
session.setAttribute(ApplicationDictionary.PRINCIPAL, JSONTools.serialize(principal)); principal.setLoginTimeMillis(currentTimeMillis);
session.setAttribute(ApplicationDictionary.USER_SESSION_LOGIN_TIME, currentTimeMillis); String token = UUID.randomUUID().toString();
// stringRedisTemplate.opsForValue().set(principal.getUserInfo().getUsername(), token, 3, TimeUnit.HOURS);
loginOperations.set(token, principal, 3, TimeUnit.HOURS);
// session.setAttribute(ApplicationDictionary.PRINCIPAL, JSONTools.serialize(principal));
// session登陆时间,毫秒值 // session登陆时间,毫秒值
// 用户登陆时间,毫秒值 session.setAttribute(ApplicationDictionary.USER_SESSION_LOGIN_TIME, currentTimeMillis);
loginInfo.put(userInfo.getUserId() + "", currentTimeMillis);
// 保存用户最后登陆时间 // 保存用户最后登陆时间
user.setLastLoginTime(new Date()); user.setLastLoginTime(new Date());
userService.updateUser(user); userService.updateUser(user);
log.info("登陆成功sessionId="+ session.getId()); // log.info("登陆成功sessionId="+ session.getId());
return new Tuple<>(Boolean.TRUE, ApplicationStatus.SUCCESS); return new Tuple<>(ApplicationStatus.SUCCESS, token);
} }
/** /**
...@@ -106,6 +115,10 @@ public class LoginServiceImpl implements LoginService { ...@@ -106,6 +115,10 @@ public class LoginServiceImpl implements LoginService {
*/ */
@Override @Override
public boolean logout() { public boolean logout() {
String bossToken = Application.getBossToken(request);
if (StringUtils.isNotEmpty(bossToken)) {
loginOperations.getOperations().delete(bossToken);
}
this.request.getSession().removeAttribute(ApplicationDictionary.PRINCIPAL); this.request.getSession().removeAttribute(ApplicationDictionary.PRINCIPAL);
...@@ -113,9 +126,4 @@ public class LoginServiceImpl implements LoginService { ...@@ -113,9 +126,4 @@ public class LoginServiceImpl implements LoginService {
} }
@Override
public Map<String, Object> getConcurrentHashMapLoginInfo() {
return loginInfo;
}
} }
...@@ -6,6 +6,7 @@ import lombok.Data; ...@@ -6,6 +6,7 @@ import lombok.Data;
import org.hibernate.annotations.Proxy; import org.hibernate.annotations.Proxy;
import javax.persistence.*; import javax.persistence.*;
import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.function.UnaryOperator; import java.util.function.UnaryOperator;
...@@ -16,7 +17,7 @@ import java.util.function.UnaryOperator; ...@@ -16,7 +17,7 @@ import java.util.function.UnaryOperator;
@Entity @Entity
@Table(name = "role") @Table(name = "role")
@Proxy(lazy = false) @Proxy(lazy = false)
public class Role extends Primary implements UnaryOperator<Role> { public class Role extends Primary implements UnaryOperator<Role> , Serializable {
/** /**
* 父角色 * 父角色
......
package cn.quantgroup.cashloanflowboss.api.user.dictionary; package cn.quantgroup.cashloanflowboss.api.user.dictionary;
import java.io.Serializable;
/** /**
* Created by WeiWei on 2019/8/9. * Created by WeiWei on 2019/8/9.
*/ */
public enum UserRank { public enum UserRank implements Serializable {
/** /**
* 超级管理员(本级别直接跳过权限验证) * 超级管理员(本级别直接跳过权限验证)
......
...@@ -2,6 +2,8 @@ package cn.quantgroup.cashloanflowboss.api.user.model; ...@@ -2,6 +2,8 @@ package cn.quantgroup.cashloanflowboss.api.user.model;
import lombok.Data; import lombok.Data;
import java.io.Serializable;
/** /**
* function: * function:
* date: 2019/9/23 * date: 2019/9/23
...@@ -9,7 +11,7 @@ import lombok.Data; ...@@ -9,7 +11,7 @@ import lombok.Data;
* @author: suntao * @author: suntao
*/ */
@Data @Data
public class UserInfo { public class UserInfo implements Serializable {
private Long userId; private Long userId;
private String username; private String username;
private String nickname; private String nickname;
......
package cn.quantgroup.cashloanflowboss.core; package cn.quantgroup.cashloanflowboss.core;
import cn.quantgroup.cashloanflowboss.api.login.model.Principal; import cn.quantgroup.cashloanflowboss.api.login.model.Principal;
import cn.quantgroup.cashloanflowboss.core.constants.Constants;
import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationDictionary; import cn.quantgroup.cashloanflowboss.core.dictionary.ApplicationDictionary;
import cn.quantgroup.cashloanflowboss.utils.IpUtil; import cn.quantgroup.cashloanflowboss.utils.IpUtil;
import cn.quantgroup.cashloanflowboss.utils.JSONTools; import cn.quantgroup.cashloanflowboss.utils.JSONTools;
...@@ -207,4 +208,8 @@ public class Application implements ApplicationContextAware, ServletContextAware ...@@ -207,4 +208,8 @@ public class Application implements ApplicationContextAware, ServletContextAware
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
} }
public static String getBossToken(HttpServletRequest request) {
return request.getHeader(Constants.UI_HEADER_TOKEN);
}
} }
...@@ -319,10 +319,10 @@ public class Assert { ...@@ -319,10 +319,10 @@ public class Assert {
} }
/** /**
* @param concurrentHashMapLoginInfo 账号最后登陆时间 * @param userRealLastLoginTime 账号最后登陆时间
* *
*/ */
public static Boolean isLastLogin(Map<String, Object> concurrentHashMapLoginInfo) { public static Boolean isLastLogin(Long userRealLastLoginTime) {
HttpSession session = Application.getSession(); HttpSession session = Application.getSession();
if (Objects.isNull(session)) { if (Objects.isNull(session)) {
return false; return false;
...@@ -332,12 +332,6 @@ public class Assert { ...@@ -332,12 +332,6 @@ public class Assert {
return false; return false;
} }
Object userLastLoginTimeObject = concurrentHashMapLoginInfo.get(principal.getUserInfo().getUserId()+"");
if (Objects.isNull(userLastLoginTimeObject)) {
// 没有登陆时间 不处理
return false;
}
// 获取session最后登陆时间 // 获取session最后登陆时间
Object creationTimeObject = session.getAttribute(ApplicationDictionary.USER_SESSION_LOGIN_TIME); Object creationTimeObject = session.getAttribute(ApplicationDictionary.USER_SESSION_LOGIN_TIME);
if (Objects.isNull(creationTimeObject)) { if (Objects.isNull(creationTimeObject)) {
...@@ -345,7 +339,7 @@ public class Assert { ...@@ -345,7 +339,7 @@ public class Assert {
} }
try { try {
if (Long.valueOf(creationTimeObject.toString()) < Long.valueOf(userLastLoginTimeObject.toString())) { if (Long.valueOf(creationTimeObject.toString()) < userRealLastLoginTime) {
return true; return true;
} }
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
......
...@@ -17,7 +17,9 @@ import org.apache.commons.collections.CollectionUtils; ...@@ -17,7 +17,9 @@ import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.ValueOperations;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
...@@ -32,10 +34,19 @@ public class ApplicationSecurityHandler implements SecurityHandler { ...@@ -32,10 +34,19 @@ public class ApplicationSecurityHandler implements SecurityHandler {
@Autowired @Autowired
private LoginService loginService; private LoginService loginService;
@Autowired
private HttpServletRequest request;
@Resource(name = "redisTemplate")
private ValueOperations<String, Principal> loginOperations;
@Override @Override
public Tuple<Boolean, ApplicationStatus> doAuthentication(MethodInvocation invocation, String authorityId, Authority[] authority) { public Tuple<Boolean, ApplicationStatus> doAuthentication(MethodInvocation invocation, String authorityId, Authority[] authority) {
Principal principal = Application.getPrincipal(); String token = Application.getBossToken(request);
Principal principal = loginOperations.get(token);
// Principal principal = Application.getPrincipal();
// 检查是否已登录 // 检查是否已登录
if (principal == null) { if (principal == null) {
...@@ -44,7 +55,7 @@ public class ApplicationSecurityHandler implements SecurityHandler { ...@@ -44,7 +55,7 @@ public class ApplicationSecurityHandler implements SecurityHandler {
} }
// 是否 被挤下线 // 是否 被挤下线
Boolean isLogin = Assert.isLastLogin(loginService.getConcurrentHashMapLoginInfo()); Boolean isLogin = Assert.isLastLogin(principal.getLoginTimeMillis());
if (BooleanUtils.isTrue(isLogin)) { if (BooleanUtils.isTrue(isLogin)) {
log.info("已在其他地方登陆,需要重新登陆,userName=" + principal.getUserInfo().getUsername()); log.info("已在其他地方登陆,需要重新登陆,userName=" + principal.getUserInfo().getUsername());
// 退出登陆 // 退出登陆
......
...@@ -14,4 +14,5 @@ public interface Constants { ...@@ -14,4 +14,5 @@ public interface Constants {
String TOKEN = "token"; String TOKEN = "token";
String TRUE = "true"; String TRUE = "true";
String START_THIS = "#this"; String START_THIS = "#this";
String UI_HEADER_TOKEN = "boss_token";
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment