|
@@ -1,20 +1,24 @@
|
|
|
package com.nokia.service;
|
|
|
|
|
|
+import com.alibaba.fastjson2.JSON;
|
|
|
+import com.nokia.common.R;
|
|
|
+import com.nokia.constants.ClientEnum;
|
|
|
import com.nokia.dao.UserDao;
|
|
|
import com.nokia.dao.VerificationLogDao;
|
|
|
import com.nokia.pojo.User;
|
|
|
import com.nokia.pojo.VerificationLog;
|
|
|
-import com.nokia.vo.AppVerificationVO;
|
|
|
-import com.nokia.vo.TokenFlagVo;
|
|
|
-import com.nokia.vo.TokenVo;
|
|
|
+import com.nokia.vo.*;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import java.time.LocalDateTime;
|
|
|
+import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
@Slf4j
|
|
@@ -23,6 +27,13 @@ public class AclService {
|
|
|
|
|
|
@Value("${redis.timeoutSeconds:600}")
|
|
|
private Integer timeoutSeconds;
|
|
|
+ /*
|
|
|
+ * 重定向的url,解决当token失效时的重定向问题
|
|
|
+ */
|
|
|
+ @Value("${dop.redirect.url}")
|
|
|
+ private String dopRedirectUrl;
|
|
|
+ @Value("${top.redirect.url}")
|
|
|
+ private String topRedirectUrl;
|
|
|
|
|
|
private final UserDao userDao;
|
|
|
private final TopService topService;
|
|
@@ -43,7 +54,115 @@ public class AclService {
|
|
|
this.verificationLogDao = verificationLogDao;
|
|
|
}
|
|
|
|
|
|
- public List<AppVerificationVO> listUserFunctions(TokenVo tokenEntity, Integer userId, Integer client) {
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public R verifySystem(TokenVo tokenEntity) {
|
|
|
+ Map<String, String> map = new HashMap<>();
|
|
|
+ if (tokenEntity.getFromSystem().equalsIgnoreCase("top")) {
|
|
|
+ map.put("redirect", topRedirectUrl);
|
|
|
+ } else if (tokenEntity.getFromSystem().equalsIgnoreCase("dop")) {
|
|
|
+ map.put("redirect", dopRedirectUrl);
|
|
|
+ } else {
|
|
|
+ // 根据接入的系统不同,返回不同的重定向url
|
|
|
+ switch (tokenEntity.getSystem().trim().toLowerCase()) {
|
|
|
+ case "daping":
|
|
|
+ map.put("redirect", dopRedirectUrl);
|
|
|
+ break;
|
|
|
+ // case "liucheng":
|
|
|
+ // case "fenxi":
|
|
|
+ // case "yuce":
|
|
|
+ // case "heidianku":
|
|
|
+ default:
|
|
|
+ map.put("redirect", topRedirectUrl);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ String token = tokenEntity.getToken();
|
|
|
+ String fromSystem = tokenEntity.getFromSystem();
|
|
|
+ String system = tokenEntity.getSystem();
|
|
|
+ // 为不同system生成不同key
|
|
|
+ String key = system + ":" + token;
|
|
|
+ User userEntity;
|
|
|
+ // 从redis中查询
|
|
|
+ userEntity = (User) redisTemplate.opsForValue().get(key);
|
|
|
+ if (userEntity != null) {
|
|
|
+ log.debug("redis查询成功: {}", userEntity);
|
|
|
+ // 2.1 可以查到用户信息,重置redis中的用户信息,刷新到期时间
|
|
|
+ redisTemplate.opsForValue().set(token, userEntity, timeoutSeconds, TimeUnit.SECONDS);
|
|
|
+ return res(tokenEntity, userEntity, map);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2.2 无法查到用户信息 可能是已超timeoutSeconds或者是初次登录
|
|
|
+ // 需要根据fromSystem参数去对应的系统进行鉴权
|
|
|
+ TokenFlagVo tokenFlagVo = getVerifyResult(token, fromSystem);
|
|
|
+ if (tokenFlagVo == null || !tokenFlagVo.isValid()) {
|
|
|
+ // token无效,返回重定向的登陆地址
|
|
|
+ return R.error().data(map).message("用户不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果token状态为可用,根据loginName从数据库查询用户
|
|
|
+ // 这里存在一个问题,如果是在top已存在的用户,但是我们系统没有,此时返回的userEntity为null,会对后续处理产生影响,需要考虑应该怎么做
|
|
|
+ // 在前端处理,上面的问题仅影响初次点击入口的用户,不影响超时用户
|
|
|
+ // 前端需要对入口用户做特别的处理
|
|
|
+ userEntity = userDao.getByLoginName(tokenFlagVo.getLoginName());
|
|
|
+ if (userEntity == null) {
|
|
|
+ return R.error().data(map).message("用户不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 仅当用户信息不为空时,将用户信息存入redis
|
|
|
+ redisTemplate.opsForValue().set(key, userEntity, timeoutSeconds, TimeUnit.SECONDS);
|
|
|
+ R r = res(tokenEntity, userEntity, map);
|
|
|
+ Integer success = Boolean.TRUE.equals(r.getSuccess()) ? 1 : 0;
|
|
|
+ String res = JSON.toJSONString(r);
|
|
|
+ // redis保存新token信息,记录登录日志
|
|
|
+ logVerification(tokenEntity, userEntity, success, res);
|
|
|
+ log.info("{}登录{}", userEntity.getLoginName(), tokenEntity.getSystem());
|
|
|
+ return r;
|
|
|
+ }
|
|
|
+
|
|
|
+ private R res(TokenVo tokenEntity, User userEntity, Map<String, String> map) {
|
|
|
+ switch (tokenEntity.getSystem().trim().toLowerCase()) {
|
|
|
+ case "liucheng":
|
|
|
+ return R.ok().data(new LiuchengUserVo(userEntity));
|
|
|
+ case "fenxi":
|
|
|
+ FenxiUserVo fenxiUserVo = new FenxiUserVo(userEntity);
|
|
|
+ if (fenxiUserVo.getCity() == null) {
|
|
|
+ return R.error().data(map).message("用户不存在");
|
|
|
+ }
|
|
|
+ return R.ok().data(fenxiUserVo);
|
|
|
+ case "daping":
|
|
|
+ DapingUserVo dapingUserVo = new DapingUserVo(userEntity);
|
|
|
+ if (dapingUserVo.getCity() == null) {
|
|
|
+ return R.error().data(map).message("用户不存在");
|
|
|
+ }
|
|
|
+ return R.ok().data(dapingUserVo);
|
|
|
+ case "yuce":
|
|
|
+ YuceUserVo yuceUserVo = new YuceUserVo(userEntity);
|
|
|
+ if (yuceUserVo.getCity() == null) {
|
|
|
+ return R.error().data(map).message("用户不存在");
|
|
|
+ }
|
|
|
+ return R.ok().data(yuceUserVo);
|
|
|
+ case "heidianku": // 黑点库
|
|
|
+ HeidiankuUserVo heidiankuUserVo = new HeidiankuUserVo(userEntity);
|
|
|
+ if (heidiankuUserVo.getCity() == null) {
|
|
|
+ return R.error().data(map).message("用户不存在");
|
|
|
+ }
|
|
|
+ return R.ok().data(heidiankuUserVo);
|
|
|
+ case "volte_t2": // volte分析T2页面
|
|
|
+ VolteT2UserVo userVo = new VolteT2UserVo(userEntity);
|
|
|
+ return R.ok().data(userVo);
|
|
|
+ case "luyin":
|
|
|
+ LvYinVo lvYinVo = new LvYinVo(userEntity);
|
|
|
+ return R.ok().data(lvYinVo);
|
|
|
+ case "app":
|
|
|
+ List<AppVerificationVO> vo = listUserFunctions(tokenEntity, userEntity.getUserId(),
|
|
|
+ ClientEnum.APP.value);
|
|
|
+ return R.ok().data(vo);
|
|
|
+ default:
|
|
|
+ return R.error().message("当前允许的system为: liucheng/fenxi/daping/yuce/heidianku/volte_t2/luyin/app");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<AppVerificationVO> listUserFunctions(TokenVo tokenEntity, Integer userId, Integer client) {
|
|
|
List<AppVerificationVO> list = userDao.listUserFunctions(userId, client);
|
|
|
for (AppVerificationVO t : list) {
|
|
|
t.setUrl(t.getUrl() + "&fromSystem=" + tokenEntity.getFromSystem() + "&token=" + tokenEntity.getToken());
|
|
@@ -51,7 +170,7 @@ public class AclService {
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
- public void logVerification(TokenVo tokenEntity, User userEntity) {
|
|
|
+ private void logVerification(TokenVo tokenEntity, User userEntity, Integer success, String res) {
|
|
|
VerificationLog verificationLog = new VerificationLog();
|
|
|
verificationLog.setUserId(userEntity.getUserId());
|
|
|
verificationLog.setLoginName(userEntity.getLoginName());
|
|
@@ -59,50 +178,11 @@ public class AclService {
|
|
|
verificationLog.setCityId(userEntity.getCityId());
|
|
|
verificationLog.setSystem(tokenEntity.getSystem());
|
|
|
verificationLog.setLoginTime(LocalDateTime.now());
|
|
|
+ verificationLog.setSuccess(success);
|
|
|
+ verificationLog.setRes(res);
|
|
|
verificationLogDao.insert(verificationLog);
|
|
|
}
|
|
|
|
|
|
- public User verifySystem(TokenVo tokenVo) {
|
|
|
- String token = tokenVo.getToken();
|
|
|
- String fromSystem = tokenVo.getFromSystem();
|
|
|
- String system = tokenVo.getSystem();
|
|
|
- // 为不同system生成不同key
|
|
|
- String key = system + ":" + token;
|
|
|
- User userEntity;
|
|
|
- // 从redis中查询
|
|
|
- userEntity = (User) redisTemplate.opsForValue().get(key);
|
|
|
- if (userEntity != null) {
|
|
|
- log.debug("redis查询成功: {}", userEntity);
|
|
|
- // 2.1 可以查到用户信息,重置redis中的用户信息,刷新到期时间
|
|
|
- redisTemplate.opsForValue().set(token, userEntity, timeoutSeconds, TimeUnit.SECONDS);
|
|
|
- // 3 返回用户信息
|
|
|
- return userEntity;
|
|
|
- } else {
|
|
|
- // 2.2 无法查到用户信息 可能是已超timeoutSeconds或者是初次登录
|
|
|
- // 需要根据fromSystem参数去对应的系统进行鉴权
|
|
|
- TokenFlagVo tokenFlagVo = getVerifyResult(token, fromSystem);
|
|
|
- if (tokenFlagVo != null && tokenFlagVo.isValid()) {
|
|
|
- // 如果token状态为可用,根据loginName从数据库查询用户
|
|
|
- // 这里存在一个问题,如果是在top已存在的用户,但是我们系统没有,此时返回的userEntity为null,会对后续处理产生影响,需要考虑应该怎么做
|
|
|
- // 在前端处理,上面的问题仅影响初次点击入口的用户,不影响超时用户
|
|
|
- // 前端需要对入口用户做特别的处理
|
|
|
- userEntity = userDao.getByLoginName(tokenFlagVo.getLoginName());
|
|
|
- if (userEntity != null) {
|
|
|
- // 仅当用户信息不为空时,将用户信息存入redis
|
|
|
- redisTemplate.opsForValue().set(key, userEntity, timeoutSeconds, TimeUnit.SECONDS);
|
|
|
- // redis保存新token信息,记录登录日志
|
|
|
- logVerification(tokenVo, userEntity);
|
|
|
- log.info("{}登录{}", userEntity.getLoginName(), tokenVo.getSystem());
|
|
|
- }
|
|
|
- // 返回用户信息
|
|
|
- return userEntity;
|
|
|
- } else {
|
|
|
- // token无效,返回重定向的登陆地址
|
|
|
- return null;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
private TokenFlagVo getVerifyResult(String token, String fromSystem) {
|
|
|
if (fromSystem.trim().equalsIgnoreCase("dop")) {
|
|
|
return dopService.dopReturn(token);
|