Commit da051007 authored by xuepeng.chang's avatar xuepeng.chang

获取用户的登陆渠道和踢出

parent a841d056
package cn.quantgroup.xyqb.controller.api.v2; package cn.quantgroup.xyqb.controller.api.v2;
import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.constant.UserConstant;
import cn.quantgroup.xyqb.controller.IBaseController; import cn.quantgroup.xyqb.controller.IBaseController;
import cn.quantgroup.xyqb.controller.req.v2.BatchInfoReq; import cn.quantgroup.xyqb.controller.req.v2.BatchInfoReq;
import cn.quantgroup.xyqb.controller.req.v2.KickOutReq;
import cn.quantgroup.xyqb.controller.req.v2.LogInChannelReq;
import cn.quantgroup.xyqb.controller.req.v2.UserInfoReq; import cn.quantgroup.xyqb.controller.req.v2.UserInfoReq;
import cn.quantgroup.xyqb.entity.BaseEntity; import cn.quantgroup.xyqb.entity.BaseEntity;
import cn.quantgroup.xyqb.entity.User; import cn.quantgroup.xyqb.entity.User;
...@@ -12,9 +16,12 @@ import cn.quantgroup.xyqb.exception.BizExceptionEnum; ...@@ -12,9 +16,12 @@ import cn.quantgroup.xyqb.exception.BizExceptionEnum;
import cn.quantgroup.xyqb.exception.SilentBizException; import cn.quantgroup.xyqb.exception.SilentBizException;
import cn.quantgroup.xyqb.model.JsonResult; import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.model.UserBean; import cn.quantgroup.xyqb.model.UserBean;
import cn.quantgroup.xyqb.model.UserLoginVO;
import cn.quantgroup.xyqb.model.session.SessionStruct; import cn.quantgroup.xyqb.model.session.SessionStruct;
import cn.quantgroup.xyqb.repository.IUserInfoRepository; import cn.quantgroup.xyqb.repository.IUserInfoRepository;
import cn.quantgroup.xyqb.repository.IUserRepository; import cn.quantgroup.xyqb.repository.IUserRepository;
import cn.quantgroup.xyqb.service.session.ISessionService;
import cn.quantgroup.xyqb.service.session.impl.SessionServiceImpl;
import cn.quantgroup.xyqb.service.wechat.IWechatService; import cn.quantgroup.xyqb.service.wechat.IWechatService;
import cn.quantgroup.xyqb.session.XyqbSessionContextHolder; import cn.quantgroup.xyqb.session.XyqbSessionContextHolder;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
...@@ -22,10 +29,7 @@ import com.google.common.collect.Lists; ...@@ -22,10 +29,7 @@ import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -39,10 +43,14 @@ public class UserApiV2Controller implements IBaseController { ...@@ -39,10 +43,14 @@ public class UserApiV2Controller implements IBaseController {
private final IWechatService wechatService; private final IWechatService wechatService;
private final IUserInfoRepository userInfoRepository; private final IUserInfoRepository userInfoRepository;
public UserApiV2Controller(IUserRepository userRepository, IWechatService wechatService,IUserInfoRepository userInfoRepository) { private final ISessionService sessionService;
public UserApiV2Controller(IUserRepository userRepository, IWechatService wechatService,IUserInfoRepository userInfoRepository,
ISessionService sessionService) {
this.userRepository = userRepository; this.userRepository = userRepository;
this.wechatService = wechatService; this.wechatService = wechatService;
this.userInfoRepository = userInfoRepository; this.userInfoRepository = userInfoRepository;
this.sessionService = sessionService;
} }
/** /**
...@@ -201,4 +209,29 @@ public class UserApiV2Controller implements IBaseController { ...@@ -201,4 +209,29 @@ public class UserApiV2Controller implements IBaseController {
return JsonResult.buildErrorStateResult("获取用户信息执行出错",null ); return JsonResult.buildErrorStateResult("获取用户信息执行出错",null );
} }
/**
* 获取用户当前登陆的渠道
* @param logInChannelReq
* @return
*/
@PostMapping("/obtainUserLoginChannel")
public JsonResult<UserLoginVO> obtainUserLoginChannel(@RequestBody LogInChannelReq logInChannelReq,
@RequestHeader(value = Constants.X_AUTH_TENANT,defaultValue = UserConstant.defaultTenantIdString) Integer tenantId) {
logInChannelReq.setTenantId(tenantId);
UserLoginVO userLoginVO = sessionService.obtainUserLoginChannel(logInChannelReq);
return JsonResult.buildSuccessResultGeneric(userLoginVO);
}
@PostMapping("/kickOutLogin")
public JsonResult kickOutLogin(@RequestBody KickOutReq kickOutReq,
@RequestHeader(value = Constants.X_AUTH_TENANT,defaultValue = UserConstant.defaultTenantIdString) Integer tenantId){
kickOutReq.setTenantId(tenantId);
sessionService.kickOutLogin(kickOutReq);
return JsonResult.buildSuccessResult();
}
} }
package cn.quantgroup.xyqb.controller.req.v2;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class KickOutReq {
private Long userId;
private Long registerFrom;
private Integer tenantId;
}
package cn.quantgroup.xyqb.controller.req.v2;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class LogInChannelReq {
private Long userId;
private String token;
private Integer tenantId;
}
package cn.quantgroup.xyqb.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
/**
* 返回用户当前登陆的终端渠道
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserLoginVO implements Serializable {
private static final long serialVersionUID = -1L;
/** 用户当前登陆的终端渠道*/
private Long currentRegisteredFrom;
/** 用户所有登陆的终端渠道(这里 要把金融的排除掉) */
private List<Long> registeredFromList;
}
package cn.quantgroup.xyqb.service.session; package cn.quantgroup.xyqb.service.session;
import cn.quantgroup.xyqb.controller.req.v2.KickOutReq;
import cn.quantgroup.xyqb.controller.req.v2.LogInChannelReq;
import cn.quantgroup.xyqb.entity.User; import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.model.AuthBean; import cn.quantgroup.xyqb.model.AuthBean;
import cn.quantgroup.xyqb.model.LoginProperties; import cn.quantgroup.xyqb.model.LoginProperties;
import cn.quantgroup.xyqb.model.UserLoginVO;
import cn.quantgroup.xyqb.model.session.SessionStruct; import cn.quantgroup.xyqb.model.session.SessionStruct;
import cn.quantgroup.xyqb.model.session.SessionValue; import cn.quantgroup.xyqb.model.session.SessionValue;
...@@ -65,4 +68,17 @@ public interface ISessionService { ...@@ -65,4 +68,17 @@ public interface ISessionService {
*/ */
AuthBean createSession(User user, LoginProperties loginProperties, int ordinal,Integer tenantId,boolean send); AuthBean createSession(User user, LoginProperties loginProperties, int ordinal,Integer tenantId,boolean send);
/**
* 获取当前用户登陆的所有的渠道
* @param logInChannelReq
* @return
*/
UserLoginVO obtainUserLoginChannel(LogInChannelReq logInChannelReq);
/**
* 根据渠道 踢出登录
* @param kickOutReq
*/
void kickOutLogin(KickOutReq kickOutReq);
} }
...@@ -3,11 +3,16 @@ package cn.quantgroup.xyqb.service.session.impl; ...@@ -3,11 +3,16 @@ package cn.quantgroup.xyqb.service.session.impl;
import cn.quantgroup.xyqb.Constants; import cn.quantgroup.xyqb.Constants;
import cn.quantgroup.xyqb.constant.UserConstant; import cn.quantgroup.xyqb.constant.UserConstant;
import cn.quantgroup.xyqb.constant.enums.RecordType; import cn.quantgroup.xyqb.constant.enums.RecordType;
import cn.quantgroup.xyqb.controller.req.v2.KickOutReq;
import cn.quantgroup.xyqb.controller.req.v2.LogInChannelReq;
import cn.quantgroup.xyqb.entity.User; import cn.quantgroup.xyqb.entity.User;
import cn.quantgroup.xyqb.entity.UserTag; import cn.quantgroup.xyqb.entity.UserTag;
import cn.quantgroup.xyqb.event.UserLoginEvent; import cn.quantgroup.xyqb.event.UserLoginEvent;
import cn.quantgroup.xyqb.exception.BizException;
import cn.quantgroup.xyqb.exception.BizExceptionEnum;
import cn.quantgroup.xyqb.model.AuthBean; import cn.quantgroup.xyqb.model.AuthBean;
import cn.quantgroup.xyqb.model.LoginProperties; import cn.quantgroup.xyqb.model.LoginProperties;
import cn.quantgroup.xyqb.model.UserLoginVO;
import cn.quantgroup.xyqb.model.UserStatistics; import cn.quantgroup.xyqb.model.UserStatistics;
import cn.quantgroup.xyqb.model.session.SessionStruct; import cn.quantgroup.xyqb.model.session.SessionStruct;
import cn.quantgroup.xyqb.model.session.SessionValue; import cn.quantgroup.xyqb.model.session.SessionValue;
...@@ -30,6 +35,7 @@ import org.springframework.data.redis.core.RedisTemplate; ...@@ -30,6 +35,7 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.validation.BindException;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.sql.Timestamp; import java.sql.Timestamp;
...@@ -115,6 +121,98 @@ public class SessionServiceImpl implements ISessionService { ...@@ -115,6 +121,98 @@ public class SessionServiceImpl implements ISessionService {
return authBean; return authBean;
} }
@Override
public UserLoginVO obtainUserLoginChannel(LogInChannelReq logInChannelReq) {
if(Objects.isNull(logInChannelReq) || Objects.isNull(logInChannelReq.getUserId())){
log.error("用户登录失败:非法入参:[service]:userId:{}", logInChannelReq.getUserId());
throw new BizException(BizExceptionEnum.ERROR_LOGIN_PARAM);
}
Long userId = logInChannelReq.getUserId();
Integer tenantId = logInChannelReq.getTenantId();
String setKey = getUserSessionSetKey(userId, tenantId);
Set useIdKeys = stringRedisTemplate.opsForSet().members(setKey);
log.info("[obtainUserLoginChannel]获取当前userId={}的缓存信息,useIdKeys:{}", userId, JSON.toJSONString(useIdKeys));
List<Long> registeredFromList = new ArrayList<>();
Long currentRegisteredFrom = null;
if (!CollectionUtils.isEmpty(useIdKeys)){
for (Object key : useIdKeys) {
String keyStr = String.valueOf(key);
String token = stringRedisTemplate.opsForValue().get(keyStr);
if(StringUtils.isEmpty(token)){
log.info("[obtainUserLoginChannel]获取当前userId={},key:{}的缓存信息,未获取到用户token", userId, key);
continue;
}
// 金融token 不返回
if(!token.contains(prefix)){
continue;
}
String userTokenKey = getUserTokenKey(token, tenantId);
String value = stringRedisTemplate.opsForValue().get(userTokenKey);
if(StringUtils.isEmpty(value)){
log.info("[obtainUserLoginChannel]获取当前userId={},userTokenKey:{}的缓存信息,未获取到用户token", userId, userTokenKey);
continue;
}
// userid-sessionvalue:cache::75234409:vcc:217
String[] keyParams = keyStr.split(":");
Long registeredFrom = Long.valueOf(keyParams[5]);
registeredFromList.add(registeredFrom);
if(Objects.equals(token, logInChannelReq.getToken())){
currentRegisteredFrom = registeredFrom;
}
}
}
return new UserLoginVO(currentRegisteredFrom, registeredFromList);
}
@Override
public void kickOutLogin(KickOutReq kickOutReq) {
if(Objects.isNull(kickOutReq) || Objects.isNull(kickOutReq.getUserId())
|| Objects.isNull(kickOutReq.getRegisterFrom())){
throw new BizException(BizExceptionEnum.ERROR_LOGIN_PARAM);
}
Long userId = kickOutReq.getUserId();
Integer tenantId = kickOutReq.getTenantId();
String setKey = getUserSessionSetKey(userId, tenantId);
Set useIdKeys = stringRedisTemplate.opsForSet().members(setKey);
log.info("[obtainUserLoginChannel]获取当前userId={}的缓存信息,useIdKeys:{}", userId, JSON.toJSONString(useIdKeys));
String targetToken = null;
if (!CollectionUtils.isEmpty(useIdKeys)){
for (Object key : useIdKeys) {
String keyStr = String.valueOf(key);
String token = stringRedisTemplate.opsForValue().get(keyStr);
if(StringUtils.isEmpty(token)){
log.info("[obtainUserLoginChannel]获取当前userId={},key:{}的缓存信息,未获取到用户token", userId, key);
continue;
}
// 金融token 不返回
if(!token.contains(prefix)){
continue;
}
String userTokenKey = getUserTokenKey(token, tenantId);
String value = stringRedisTemplate.opsForValue().get(userTokenKey);
if(StringUtils.isEmpty(value)){
log.info("[obtainUserLoginChannel]获取当前userId={},userTokenKey:{}的缓存信息,未获取到用户token", userId, userTokenKey);
continue;
}
// userid-sessionvalue:cache::75234409:vcc:217
String[] keyParams = keyStr.split(":");
Long registeredFrom = Long.valueOf(keyParams[5]);
if(Objects.equals(registeredFrom, kickOutReq.getRegisterFrom())){
targetToken = token;
}
}
}
if(StringUtils.isEmpty(targetToken)){
log.info("[obtainUserLoginChannel]获取当前userId={},registerFrom:{}的缓存信息,未获取到用户token", userId, kickOutReq.getRegisterFrom());
return;
}
// 用户退出
deleteSession(targetToken, tenantId);
}
@Override @Override
public SessionStruct createSessionAndPersist(User user, LoginProperties properties, Integer tenantId) { public SessionStruct createSessionAndPersist(User user, LoginProperties properties, Integer tenantId) {
......
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