Ver Fonte

登录和鉴权

wangliang há 5 anos atrás
pai
commit
655d2cedc0
22 ficheiros alterados com 366 adições e 87 exclusões
  1. 3 2
      themis-backend/src/main/java/com/qmth/themis/backend/ThemisBackendApplication.java
  2. 18 13
      themis-backend/src/main/java/com/qmth/themis/backend/api/SysController.java
  3. 18 22
      themis-backend/src/main/java/com/qmth/themis/backend/api/TBUserController.java
  4. 22 4
      themis-backend/src/main/java/com/qmth/themis/backend/interceptor/AuthInterceptor.java
  5. 2 2
      themis-backend/src/main/resources/application.properties
  6. 1 1
      themis-backend/src/main/resources/ehcache.xml
  7. 32 2
      themis-business/src/main/java/com/qmth/themis/business/constant/SystemConstant.java
  8. 14 2
      themis-business/src/main/java/com/qmth/themis/business/dto/AuthDto.java
  9. 12 12
      themis-business/src/main/java/com/qmth/themis/business/entity/TBSession.java
  10. 0 8
      themis-business/src/main/java/com/qmth/themis/business/enums/RoleEnum.java
  11. 7 0
      themis-business/src/main/java/com/qmth/themis/business/service/TBSessionService.java
  12. 2 2
      themis-business/src/main/java/com/qmth/themis/business/service/impl/EhcacheServiceImpl.java
  13. 47 0
      themis-business/src/main/java/com/qmth/themis/business/service/impl/TBSessionServiceImpl.java
  14. 2 2
      themis-business/src/main/java/com/qmth/themis/business/util/JwtUtil.java
  15. 135 0
      themis-business/src/main/java/com/qmth/themis/business/util/RedisUtil.java
  16. 33 0
      themis-business/src/main/java/com/qmth/themis/business/util/SessionUtil.java
  17. 1 1
      themis-business/src/main/resources/mapper/TBPrivilegeMapper.xml
  18. 0 8
      themis-common/src/main/java/com/qmth/themis/common/enums/ExceptionResultEnum.java
  19. 11 1
      themis-common/src/main/java/com/qmth/themis/common/enums/Platform.java
  20. 1 1
      themis-common/src/main/java/com/qmth/themis/common/enums/Source.java
  21. 3 2
      themis-exam/src/main/java/com/qmth/themis/exam/ThemisExamApplication.java
  22. 2 2
      themis-exam/src/main/resources/application.properties

+ 3 - 2
themis-backend/src/main/java/com/qmth/themis/backend/ThemisBackendApplication.java

@@ -13,6 +13,7 @@ import org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfigura
 import org.springframework.cache.annotation.EnableCaching;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Primary;
 import org.springframework.data.redis.connection.RedisConnectionFactory;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
@@ -28,7 +29,6 @@ import org.springframework.web.multipart.commons.CommonsMultipartResolver;
 @MapperScan("com.qmth.themis.business.dao")
 //主要就是定义扫描的路径从中找出标识了需要装配的类自动装配到spring的bean容器中,做过web开发的同学一定都有用过@Controller,@Service,@Repository注解,查看其源码你会发现,他们中有一个共同的注解@Component,没错@ComponentScan注解默认就会装配标识了@Controller,@Service,@Repository,@Component注解的类到spring容器中
 @EntityScan(basePackages = {"com.qmth.themis.business.entity"})//用来扫描和发现指定包及其子包中的Entity定义
-@EnableAutoConfiguration(exclude = {MultipartAutoConfiguration.class})//
 @EnableTransactionManagement //spring开启事务支持
 @EnableScheduling //spring quartz开启
 @EnableAsync //开启异步任务
@@ -44,7 +44,7 @@ public class ThemisBackendApplication {
      *
      * @return
      */
-    @Bean(name = "multipartResolver")
+    @Bean
     public MultipartResolver multipartResolver() {
         CommonsMultipartResolver resolver = new CommonsMultipartResolver();
         resolver.setDefaultEncoding(Constants.CHARSET_NAME);
@@ -55,6 +55,7 @@ public class ThemisBackendApplication {
     }
 
     @Bean
+    @Primary
     public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
         RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
         template.setConnectionFactory(connectionFactory);

+ 18 - 13
themis-backend/src/main/java/com/qmth/themis/backend/api/SysController.java

@@ -1,23 +1,28 @@
 package com.qmth.themis.backend.api;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.qmth.themis.backend.util.ServletUtil;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.entity.TBPrivilege;
 import com.qmth.themis.business.entity.TBUser;
 import com.qmth.themis.business.enums.RoleEnum;
 import com.qmth.themis.business.service.TBPrivilegeService;
+import com.qmth.themis.business.util.JwtUtil;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.common.enums.ExceptionResultEnum;
 import com.qmth.themis.common.exception.BusinessException;
 import com.qmth.themis.common.util.Result;
 import com.qmth.themis.common.util.ResultUtil;
-import io.swagger.annotations.*;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -41,21 +46,21 @@ public class SysController {
     @ApiOperation(value = "菜单查询接口")
     @RequestMapping(value = "/getMenu", method = RequestMethod.GET)
     @ApiResponses({@ApiResponse(code = 200, message = "菜单信息", response = TBPrivilege.class)})
-    public Result getMenu(@ApiParam(value = "用户id", required = true) @RequestParam Long userId) {
-//        TBUser tbUser = (TBUser) RedisUtil.getUser(userId);
-//        if (Objects.isNull(tbUser)) {
-//            throw new BusinessException(ExceptionResultEnum.LOGIN_NO);
-//        }
-
-//        TBUser tbUser = new TBUser();
+    public Result getMenu(HttpServletRequest request) {
+        String token = ServletUtil.getRequestToken(request);
+        String userId = JwtUtil.getClaim(token, SystemConstant.JWT_USERID);
+        TBUser tbUser = (TBUser) RedisUtil.getUser(Long.parseLong(userId));
+        if (Objects.isNull(tbUser)) {
+            throw new BusinessException(ExceptionResultEnum.LOGIN_NO);
+        }
         List<TBPrivilege> tbPrivilegeList = null;
-//        if (Objects.nonNull(tbUser.getRemark()) && Objects.equals(tbUser.getRemark(), RoleEnum.SUPER_ADMIN.getCode())) {
+        if (Objects.nonNull(tbUser.getRemark()) && Objects.equals(tbUser.getRemark(), RoleEnum.SUPER_ADMIN.getCode())) {
             QueryWrapper<TBPrivilege> wrapper = new QueryWrapper<>();
             wrapper.lambda().eq(TBPrivilege::getType, SystemConstant.MENU).orderByAsc(TBPrivilege::getParentId, TBPrivilege::getSequence);
             tbPrivilegeList = tbPrivilegeService.list(wrapper);
-//        } else {
-//            tbPrivilegeList = tbPrivilegeService.getMenu(tbUser.getId());
-//        }
+        } else {
+            tbPrivilegeList = tbPrivilegeService.getMenu(tbUser.getId());
+        }
         Map map = new HashMap();
         map.put(SystemConstant.RECORDS, tbPrivilegeList);
         return ResultUtil.ok(map);

+ 18 - 22
themis-backend/src/main/java/com/qmth/themis/backend/api/TBUserController.java

@@ -3,11 +3,16 @@ package com.qmth.themis.backend.api;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.qmth.themis.backend.util.ServletUtil;
 import com.qmth.themis.business.constant.SystemConstant;
+import com.qmth.themis.business.dto.AuthDto;
+import com.qmth.themis.business.entity.TBSession;
 import com.qmth.themis.business.entity.TBUser;
 import com.qmth.themis.business.service.EhcacheService;
+import com.qmth.themis.business.service.TBSessionService;
 import com.qmth.themis.business.service.TBUserService;
 import com.qmth.themis.business.util.EhcacheUtil;
 import com.qmth.themis.business.util.JwtUtil;
+import com.qmth.themis.business.util.RedisUtil;
+import com.qmth.themis.business.util.SessionUtil;
 import com.qmth.themis.common.contanst.Constants;
 import com.qmth.themis.common.enums.ExceptionResultEnum;
 import com.qmth.themis.common.enums.Platform;
@@ -49,10 +54,10 @@ public class TBUserController {
     TBUserService tbUserService;
 
     @Resource
-    EhcacheService ehcacheService;
+    TBSessionService tbSessionService;
 
-//    private String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAK445Iw+OvQt7nGjcFSe5kLIQu/UXPEddsB9oRhncui532JXfcmJFFSGjZ+f8l134tloLh4rORNVzJ4PbikuH8U7FvSDgmgyiFTE5n0Y2E//uj95nf7ZvOeemMewtoWyCrq98Zq9HFL/+tw9E7mYa28GY+n68rSmg4zhFgGsW0ldAgMBAAECgYEAiP83yIfOt9++ViGc3Q2uJuluqUQmaXsvvCGNobEHDLXMUHpX8TgXgnfjuZd+b70r5qUjTpnSYb/gDJI5n6wjUhkbpPchMozLN359ppPB3d0bA1ZZGoFIIO5fJxIkenhUsHfZqQlNngGByK2x6SYLWwE0Y4lBx6qzMiU2E8lD3YECQQDjijWQ68G7IxqtKTYPg9LgQNCNnQgHHt/D+meZua0zAXh9ooriO2Q1xVynFTSzxOxE6K7SqofCcv/ubpILEfJxAkEAxAN2ChMPboO3ckr82nQf0Rde62K2VN1OjOAZcbVHjDluOL9dagqdRB1if47BBWoHsh1ZjQSpQdavEDM/vuUjrQJBALSKVTZH2c/Casg6isqEri2BP/kdP+FmfeXiKZGv4d02rYQCFHCs7zY7AukPymFZPp7ugMhmxpFi7e8hjH98HgECQG+BkIrWoPa7k4Y/Rmx3lwn5g5PgSd0pMGBPs+nNuG/608sQgfGrLB/tn3T1HrUXxlz6+VCRkD/WAyzyGpdb/tkCQEEEYBWuw7kVEIhgOqqrmZbVA0RFtuqpRKigJrv5YfHWZPirW9h6/mogYHr0hRFcluM/A5MM8ApwBJU2r/+Lo2k=";
-//    private String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCuOOSMPjr0Le5xo3BUnuZCyELv1FzxHXbAfaEYZ3Loud9iV33JiRRUho2fn/Jdd+LZaC4eKzkTVcyeD24pLh/FOxb0g4JoMohUxOZ9GNhP/7o/eZ3+2bznnpjHsLaFsgq6vfGavRxS//rcPRO5mGtvBmPp+vK0poOM4RYBrFtJXQIDAQAB";
+    @Resource
+    EhcacheService ehcacheService;
 
     @ApiOperation(value = "用户登录接口")
     @RequestMapping(value = "/login/account", method = RequestMethod.POST)
@@ -89,28 +94,19 @@ public class TBUserController {
         String deviceId = ServletUtil.getRequestDeviceId(request);
         //生成token
         String token = JwtUtil.sign(user.getId(), platform, deviceId);
-        //生成sessionId
-//        String token = AccessToken.build(String.valueOf(user.getId()), Platform.PC, "1");
-//        log.info("token start");
-//        long start = System.currentTimeMillis();
-//        RSAPrivateKey rsaPrivateKey = RSAUtils.buildPrivateKey(privateKey);
-//        for (int i = 0; i < 1000000; i++) {
-//            String token = VerifyToken.encode(String.valueOf(i), Platform.PC, "1", rsaPrivateKey);
-//        }
-////        String token = VerifyToken.encode(String.valueOf(user.getId()), Platform.PC, "1", rsaPrivateKey);
-//        long end = System.currentTimeMillis();
-//        log.info("token end,耗时:{}s", (end - start) / 1000);
-//        RSAPublicKey rsaPublicKey = RSAUtils.buildPublicKey(publicKey);
-//        VerifyToken result = VerifyToken.decode(token, rsaPublicKey);
-//        log.info("result:{}", JSONObject.toJSONString(result));
-        //生成sessionId
+        //添加用户鉴权缓存
+        AuthDto authDto = ehcacheService.addAccountCache(user);
+        EhcacheUtil.get(SystemConstant.AUTH_CACHE, user.getId());
         //添加用户缓存
-        if (Objects.isNull(EhcacheUtil.get(SystemConstant.AUTH_CACHE, user.getId()))) {
-            ehcacheService.addAccountCache(user);
-        }
+        RedisUtil.setUser(user.getId(), platform, user);
+        //添加用户会话缓存
+        String sessionId = SessionUtil.digest(user.getId(), authDto.getRoleEnum().name(), platform.getSource());
+        TBSession tbSession = tbSessionService.saveSessionInfo(sessionId, user.getId(), authDto.getRoleEnum().name(), platform.name(), platform.getSource(), deviceId, token, request.getLocalAddr());
+        RedisUtil.setUserSession(sessionId, platform, tbSession);
+
         Map<String, Object> map = new HashMap<>();
         map.put(SystemConstant.TOKEN, token);
-        map.put(SystemConstant.ACCOUNT, user);
+        map.put(SystemConstant.USER, user);
         return ResultUtil.ok(map);
     }
 

+ 22 - 4
themis-backend/src/main/java/com/qmth/themis/backend/interceptor/AuthInterceptor.java

@@ -4,9 +4,12 @@ import com.qmth.themis.backend.config.DictionaryConfig;
 import com.qmth.themis.backend.util.ServletUtil;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dto.AuthDto;
+import com.qmth.themis.business.entity.TBSession;
 import com.qmth.themis.business.service.EhcacheService;
 import com.qmth.themis.business.util.EhcacheUtil;
 import com.qmth.themis.business.util.JwtUtil;
+import com.qmth.themis.business.util.RedisUtil;
+import com.qmth.themis.business.util.SessionUtil;
 import com.qmth.themis.common.enums.ExceptionResultEnum;
 import com.qmth.themis.common.enums.Platform;
 import com.qmth.themis.common.exception.BusinessException;
@@ -18,6 +21,7 @@ import org.springframework.web.servlet.ModelAndView;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.util.Date;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
@@ -55,11 +59,11 @@ public class AuthInterceptor implements HandlerInterceptor {
         if (Objects.isNull(token)) {
             throw new BusinessException(ExceptionResultEnum.TOKEN_INVALID);
         }
-//        if (Objects.isNull(deviceId)) {
-//            throw new BusinessException(ExceptionResultEnum.DEVICE_ID_INVALID);
-//        }
+        if (Objects.isNull(deviceId)) {
+            throw new BusinessException(ExceptionResultEnum.DEVICE_ID_INVALID);
+        }
         String userId = JwtUtil.getClaim(token, SystemConstant.JWT_USERID);
-        //首先验证token
+        //首先验证token是否匹配
         if (!JwtUtil.verify(token, Long.parseLong(userId), platform, deviceId)) {
             throw new BusinessException(ExceptionResultEnum.TOKEN_NO);
         }
@@ -75,6 +79,20 @@ public class AuthInterceptor implements HandlerInterceptor {
         if (Objects.isNull(authDto)) {
             authDto = ehcacheService.addAccountCache(userId);
         }
+        //验证token是否有效
+        String sessionId = SessionUtil.digest(Long.parseLong(userId), authDto.getRoleEnum().name(), platform.getSource());
+        TBSession tbSession = (TBSession) RedisUtil.getUserSession(sessionId);
+        if (Objects.isNull(tbSession)) {
+            throw new BusinessException(ExceptionResultEnum.LOGIN_NO);
+        } else {
+            if (!Objects.equals(token, tbSession.getAccessToken())) {
+                throw new BusinessException(ExceptionResultEnum.TOKEN_NO);
+            }
+            Date expireTime = tbSession.getExpireTime();
+            if (expireTime.getTime() <= System.currentTimeMillis()) {
+                throw new BusinessException(ExceptionResultEnum.TOKEN_NO);
+            }
+        }
         //验证权限
         Set<String> urls = authDto.getUrls();
         int count = (int) urls.stream().filter(s -> {

+ 2 - 2
themis-backend/src/main/resources/application.properties

@@ -19,7 +19,7 @@ db.username=root
 db.password=123456789
 #redis\u6570\u636E\u6E90\u914D\u7F6E
 redis.host=${db.host}
-redis.database=0
+redis.database=15
 redis.port=6379
 redis.password=
 spring.datasource.url=jdbc:mysql://${db.host}:${db.port}/${db.name}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8
@@ -70,7 +70,7 @@ mybatis-plus.mapper-locations=classpath:/mapper/*Mapper.xml
 mybatis-plus.global-config.id-type=1
 mybatis-plus.configuration.map-underscore-to-camel-case=true
 mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
-logging.level.com.qmth.themis.backend.mapper=debug
+logging.level.com.qmth.themis.business.dao=debug
 mybatis-plus.configuration.call-setters-on-nulls=true
 
 #redis

+ 1 - 1
themis-backend/src/main/resources/ehcache.xml

@@ -22,6 +22,6 @@
             overflowToDisk="false"
             diskPersistent="false"
             timeToIdleSeconds="0"
-            timeToLiveSeconds="2400"
+            timeToLiveSeconds="43200"
             memoryStoreEvictionPolicy="LRU" />
 </ehcache>

+ 32 - 2
themis-business/src/main/java/com/qmth/themis/business/constant/SystemConstant.java

@@ -1,5 +1,11 @@
 package com.qmth.themis.business.constant;
 
+import com.qmth.themis.common.enums.Platform;
+import com.qmth.themis.common.enums.Source;
+
+import java.util.Date;
+import java.util.Objects;
+
 /**
  * @Description: 系统常量
  * @Param:
@@ -29,7 +35,8 @@ public class SystemConstant {
      */
     public static final String SUCCESS = "{'success':true}";
     public static final String RECORDS = "records";
-    public static final String ACCOUNT = "account";
+    public static final String USER = "user_";
+    public static final String SESSION = "session_";
     public static final String LINK = "LINK";
     public static final String MENU = "MENU";
     public static final String AUTH_CACHE = "auth_cache";
@@ -38,5 +45,28 @@ public class SystemConstant {
     public static final String JWT_USERID = "userId";
     public static final String JWT_SECRET = "YuiopB0009Xn";//jwt密钥
     public static final String JWT_CURRENT_TIME = "currentTimeMillis";
-    public static final int JWT_EXPIRE_TIME = 60 * 720 * 1000;//过期时间12小时
+    public static final long JWT_WEB_EXPIRE_TIME = 60L * 1440L * 1000L;//过期时间24小时
+    public static final long JWT_PC_EXPIRE_TIME = 60L * 1440L * 1000L;//过期时间24小时
+    public static final long JWT_PAD_EXPIRE_TIME = 60L * 1440L * 1000L;//过期时间24小时
+    public static final long JWT_PHONE_EXPIRE_TIME = 60L * 43200L * 1000L;//过期时间30天
+
+    /**
+     * 获取过期时间
+     *
+     * @param platform
+     * @return
+     */
+    public static long expireTime(Platform platform) {
+        Long expireTime = null;
+        if (Objects.equals(platform.getSource(), Source.Web.name())) {
+            expireTime = SystemConstant.JWT_WEB_EXPIRE_TIME;
+        } else if (Objects.equals(platform.getSource(), Source.PC.name())) {
+            expireTime = SystemConstant.JWT_PC_EXPIRE_TIME;
+        } else if (Objects.equals(platform.getSource(), Source.Pad.name())) {
+            expireTime = SystemConstant.JWT_PAD_EXPIRE_TIME;
+        } else if (Objects.equals(platform.getSource(), Source.Phone.name())) {
+            expireTime = SystemConstant.JWT_PHONE_EXPIRE_TIME;
+        }
+        return expireTime.longValue();
+    }
 }

+ 14 - 2
themis-business/src/main/java/com/qmth/themis/business/dto/AuthDto.java

@@ -1,5 +1,7 @@
 package com.qmth.themis.business.dto;
 
+import com.qmth.themis.business.enums.RoleEnum;
+
 import java.io.Serializable;
 import java.util.Set;
 
@@ -13,14 +15,16 @@ import java.util.Set;
 public class AuthDto implements Serializable {
     private static final long serialVersionUID = 1L;
 
+    private RoleEnum roleEnum;
     private Set<String> roleCodes;
     private Set<String> urls;
 
-    public AuthDto(){
+    public AuthDto() {
 
     }
 
-    public AuthDto(Set<String> roleCodes, Set<String> urls) {
+    public AuthDto(RoleEnum roleEnum, Set<String> roleCodes, Set<String> urls) {
+        this.roleEnum = roleEnum;
         this.roleCodes = roleCodes;
         this.urls = urls;
     }
@@ -29,6 +33,14 @@ public class AuthDto implements Serializable {
         return serialVersionUID;
     }
 
+    public RoleEnum getRoleEnum() {
+        return roleEnum;
+    }
+
+    public void setRoleEnum(RoleEnum roleEnum) {
+        this.roleEnum = roleEnum;
+    }
+
     public Set<String> getRoleCodes() {
         return roleCodes;
     }

+ 12 - 12
themis-business/src/main/java/com/qmth/themis/business/entity/TBSession.java

@@ -22,7 +22,7 @@ public class TBSession implements Serializable {
 
     @ApiModelProperty(value = "主键")
     @TableId(value = "id")
-    private Long id;
+    private String id;
 
     @ApiModelProperty(value = "用户标识")
     @TableId(value = "identity")
@@ -30,15 +30,15 @@ public class TBSession implements Serializable {
 
     @ApiModelProperty(value = "用户类型")
     @TableId(value = "type")
-    private Integer type;
+    private String type;
 
     @ApiModelProperty(value = "访问来源")
     @TableId(value = "source")
-    private Integer source;
+    private String source;
 
     @ApiModelProperty(value = "设备分类")
     @TableId(value = "platform")
-    private Integer platform;
+    private String platform;
 
     @ApiModelProperty(value = "设备标识")
     @TableField("device_id")
@@ -72,11 +72,11 @@ public class TBSession implements Serializable {
         return serialVersionUID;
     }
 
-    public Long getId() {
+    public String getId() {
         return id;
     }
 
-    public void setId(Long id) {
+    public void setId(String id) {
         this.id = id;
     }
 
@@ -88,27 +88,27 @@ public class TBSession implements Serializable {
         this.identity = identity;
     }
 
-    public Integer getType() {
+    public String getType() {
         return type;
     }
 
-    public void setType(Integer type) {
+    public void setType(String type) {
         this.type = type;
     }
 
-    public Integer getSource() {
+    public String getSource() {
         return source;
     }
 
-    public void setSource(Integer source) {
+    public void setSource(String source) {
         this.source = source;
     }
 
-    public Integer getPlatform() {
+    public String getPlatform() {
         return platform;
     }
 
-    public void setPlatform(Integer platform) {
+    public void setPlatform(String platform) {
         this.platform = platform;
     }
 

+ 0 - 8
themis-business/src/main/java/com/qmth/themis/business/enums/RoleEnum.java

@@ -68,15 +68,7 @@ public enum RoleEnum {
         return id;
     }
 
-    public void setId(int id) {
-        this.id = id;
-    }
-
     public String getCode() {
         return code;
     }
-
-    public void setCode(String code) {
-        this.code = code;
-    }
 }

+ 7 - 0
themis-business/src/main/java/com/qmth/themis/business/service/TBSessionService.java

@@ -12,4 +12,11 @@ import com.qmth.themis.business.entity.TBSession;
  */
 public interface TBSessionService extends IService<TBSession> {
 
+    /**
+     * 保存session信息
+     *
+     * @param o
+     * @return
+     */
+    TBSession saveSessionInfo(Object... o);
 }

+ 2 - 2
themis-business/src/main/java/com/qmth/themis/business/service/impl/EhcacheServiceImpl.java

@@ -76,7 +76,7 @@ public class EhcacheServiceImpl implements EhcacheService {
                     QueryWrapper<TBPrivilege> pWrapper = new QueryWrapper<>();
                     pWrapper.lambda().eq(TBPrivilege::getType, SystemConstant.LINK);
                     List<TBPrivilege> tbPrivilegeList = tbPrivilegeService.list(pWrapper);
-                    authDto = new AuthDto(tbUserRoleList.stream().map(s -> s.getRoleCode()).collect(Collectors.toSet()), tbPrivilegeList.stream().map(s -> s.getUrl()).collect(Collectors.toSet()));
+                    authDto = new AuthDto(RoleEnum.SUPER_ADMIN, tbUserRoleList.stream().map(s -> s.getRoleCode()).collect(Collectors.toSet()), tbPrivilegeList.stream().map(s -> s.getUrl()).collect(Collectors.toSet()));
                     EhcacheUtil.put(SystemConstant.AUTH_CACHE, user.getId(), authDto);
                 } else {
                     //根据角色名查权限
@@ -88,7 +88,7 @@ public class EhcacheServiceImpl implements EhcacheService {
                     QueryWrapper<TBPrivilege> pWrapper = new QueryWrapper<>();
                     pWrapper.lambda().in(TBPrivilege::getId, privilegeIds).eq(TBPrivilege::getType, SystemConstant.LINK);
                     List<TBPrivilege> tbPrivilegeList = tbPrivilegeService.list(pWrapper);
-                    authDto = new AuthDto(tbUserRoleList.stream().map(s -> s.getRoleCode()).collect(Collectors.toSet()), tbPrivilegeList.stream().map(s -> s.getUrl()).collect(Collectors.toSet()));
+                    authDto = new AuthDto(RoleEnum.valueOf(tbRolePrivilegeList.get(0).getRoleCode()), tbUserRoleList.stream().map(s -> s.getRoleCode()).collect(Collectors.toSet()), tbPrivilegeList.stream().map(s -> s.getUrl()).collect(Collectors.toSet()));
                     EhcacheUtil.put(SystemConstant.AUTH_CACHE, user.getId(), authDto);
                 }
             }

+ 47 - 0
themis-business/src/main/java/com/qmth/themis/business/service/impl/TBSessionServiceImpl.java

@@ -1,11 +1,16 @@
 package com.qmth.themis.business.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.themis.business.dao.TBSessionMapper;
 import com.qmth.themis.business.entity.TBSession;
 import com.qmth.themis.business.service.TBSessionService;
+import com.qmth.themis.business.util.JwtUtil;
 import org.springframework.stereotype.Service;
 
+import java.util.Date;
+import java.util.Objects;
+
 /**
  * @Description: 会话信息 服务实现类
  * @Param:
@@ -16,4 +21,46 @@ import org.springframework.stereotype.Service;
 @Service
 public class TBSessionServiceImpl extends ServiceImpl<TBSessionMapper, TBSession> implements TBSessionService {
 
+    /**
+     * 保存session信息
+     *
+     * @param o
+     * @return
+     */
+    @Override
+    public TBSession saveSessionInfo(Object... o) {
+        String id = String.valueOf(o[0]);
+        String type = String.valueOf(o[2]);
+        String platform = String.valueOf(o[3]);
+        String source = String.valueOf(o[4]);
+        String deviceId = String.valueOf(o[5]);
+        String token = String.valueOf(o[6]);
+        String ip = String.valueOf(o[7]);
+        QueryWrapper<TBSession> sqw = new QueryWrapper<>();
+        sqw.lambda().eq(TBSession::getId, id).eq(TBSession::getType, type).eq(TBSession::getPlatform, platform);
+        TBSession tbSession = this.getOne(sqw);
+        if (Objects.isNull(tbSession)) {
+            tbSession = new TBSession();
+            tbSession.setId(id);
+            tbSession.setIdentity(String.valueOf(o[1]));
+            tbSession.setType(type);
+            tbSession.setPlatform(platform);
+            tbSession.setSource(source);
+            tbSession.setDeviceId(deviceId);
+            tbSession.setAccessToken(token);
+            tbSession.setAddress(ip);
+            tbSession.setLastAccessTime(new Date());
+            tbSession.setUpdateTime(new Date());
+            tbSession.setExpireTime(JwtUtil.getExpirationDateFromToken(token));
+        } else {
+            tbSession.setDeviceId(deviceId);
+            tbSession.setAccessToken(token);
+            tbSession.setLastAccessIp(ip);
+            tbSession.setLastAccessTime(new Date());
+            tbSession.setUpdateTime(new Date());
+            tbSession.setExpireTime(JwtUtil.getExpirationDateFromToken(token));
+        }
+        this.saveOrUpdate(tbSession);
+        return tbSession;
+    }
 }

+ 2 - 2
themis-business/src/main/java/com/qmth/themis/business/util/JwtUtil.java

@@ -103,7 +103,7 @@ public class JwtUtil {
         try {
             String secret = userId + SystemConstant.JWT_SECRET;
             Long start = System.currentTimeMillis();
-            Date date = new Date(start + SystemConstant.JWT_EXPIRE_TIME);
+            Date date = new Date(start + SystemConstant.JWT_WEB_EXPIRE_TIME);
             Algorithm algorithm = Algorithm.HMAC256(secret);
             // 附带username信息
             return JWT.create()
@@ -129,7 +129,7 @@ public class JwtUtil {
         try {
             String secret = userId + SystemConstant.JWT_SECRET;
             Long start = System.currentTimeMillis();
-            Date date = new Date(start + SystemConstant.JWT_EXPIRE_TIME);
+            Date date = new Date(start + SystemConstant.expireTime(platform));
             Algorithm algorithm = Algorithm.HMAC256(secret);
             // 附带username信息
             return JWT.create()

+ 135 - 0
themis-business/src/main/java/com/qmth/themis/business/util/RedisUtil.java

@@ -1,5 +1,14 @@
 package com.qmth.themis.business.util;
 
+import com.qmth.themis.business.constant.SpringContextHolder;
+import com.qmth.themis.business.constant.SystemConstant;
+import com.qmth.themis.common.enums.Platform;
+import com.qmth.themis.common.enums.Source;
+import org.springframework.data.redis.core.RedisTemplate;
+
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
 /**
  * @Description: redis util
  * @Param:
@@ -9,4 +18,130 @@ package com.qmth.themis.business.util;
  */
 public class RedisUtil {
 
+    /**
+     * 获取用户信息
+     *
+     * @param userId
+     * @return
+     */
+    public static Object getUser(Long userId) {
+        RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class);
+        return redisTemplate.opsForValue().get(SystemConstant.USER + userId);
+    }
+
+    /**
+     * 获取用户会话信息
+     *
+     * @param sessionId
+     * @return
+     */
+    public static Object getUserSession(String sessionId) {
+        RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class);
+        return redisTemplate.opsForValue().get(SystemConstant.SESSION + sessionId);
+    }
+
+    /**
+     * 设置用户信息
+     *
+     * @param userId
+     * @param o
+     */
+    public static void setUser(Long userId, Object o) {
+        RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class);
+        redisTemplate.opsForValue().set(SystemConstant.USER + userId, o, SystemConstant.JWT_WEB_EXPIRE_TIME, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 设置用户信息
+     *
+     * @param userId
+     * @param platform
+     * @param o
+     */
+    public static void setUser(Long userId, Platform platform, Object o) {
+        RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class);
+        if (Objects.equals(platform.getSource(), Source.Phone.name())) {
+            redisTemplate.opsForValue().set(SystemConstant.USER + userId, o, SystemConstant.JWT_PAD_EXPIRE_TIME, TimeUnit.SECONDS);
+        } else {
+            redisTemplate.opsForValue().set(SystemConstant.USER + userId, o, SystemConstant.expireTime(platform), TimeUnit.SECONDS);
+        }
+    }
+
+    /**
+     * 刷新用户缓存
+     *
+     * @param userId
+     */
+    public static void refreshUserCache(Long userId) {
+        RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class);
+        redisTemplate.expire(SystemConstant.USER + userId, SystemConstant.JWT_WEB_EXPIRE_TIME, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 刷新用户缓存
+     *
+     * @param userId
+     * @param platform
+     */
+    public static void refreshUserCache(Long userId, Platform platform) {
+        RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class);
+        if (Objects.equals(platform.getSource(), Source.Phone.name())) {
+            redisTemplate.expire(SystemConstant.USER + userId, SystemConstant.JWT_PAD_EXPIRE_TIME, TimeUnit.SECONDS);
+        } else {
+            redisTemplate.expire(SystemConstant.USER + userId, SystemConstant.expireTime(platform), TimeUnit.SECONDS);
+        }
+    }
+
+    /**
+     * 获取用户缓存过期时间
+     *
+     * @param userId
+     * @return
+     */
+    public static Long getUserExpire(Long userId) {
+        RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class);
+        return redisTemplate.getExpire(SystemConstant.USER + userId, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 设置用户session信息
+     *
+     * @param sessionId
+     * @param platform
+     * @param o
+     */
+    public static void setUserSession(String sessionId, Platform platform, Object o) {
+        RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class);
+        if (Objects.equals(platform.getSource(), Source.Phone.name())) {
+            redisTemplate.opsForValue().set(SystemConstant.SESSION + sessionId, o, SystemConstant.JWT_PAD_EXPIRE_TIME, TimeUnit.SECONDS);
+        } else {
+            redisTemplate.opsForValue().set(SystemConstant.SESSION + sessionId, o, SystemConstant.expireTime(platform), TimeUnit.SECONDS);
+        }
+    }
+
+    /**
+     * 刷新用户session缓存
+     *
+     * @param sessionId
+     * @param platform
+     */
+    public static void refreshUserSessionCache(String sessionId, Platform platform) {
+        RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class);
+        if (Objects.equals(platform.getSource(), Source.Phone.name())) {
+            redisTemplate.expire(SystemConstant.SESSION + sessionId, SystemConstant.JWT_PAD_EXPIRE_TIME, TimeUnit.SECONDS);
+        } else {
+            redisTemplate.expire(SystemConstant.SESSION + sessionId, SystemConstant.expireTime(platform), TimeUnit.SECONDS);
+        }
+    }
+
+    /**
+     * 获取用户session缓存过期时间
+     *
+     * @param sessionId
+     * @return
+     */
+    public static Long getUserSessionExpire(String sessionId) {
+        RedisTemplate redisTemplate = SpringContextHolder.getBean(RedisTemplate.class);
+        return redisTemplate.getExpire(SystemConstant.SESSION + sessionId, TimeUnit.SECONDS);
+    }
 }

+ 33 - 0
themis-business/src/main/java/com/qmth/themis/business/util/SessionUtil.java

@@ -0,0 +1,33 @@
+package com.qmth.themis.business.util;
+
+import com.qmth.themis.common.util.MD5Util;
+
+import java.security.NoSuchAlgorithmException;
+import java.util.Objects;
+import java.util.StringJoiner;
+
+/**
+ * @Description:
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/6/28
+ */
+public class SessionUtil {
+
+    /**
+     * 生成session
+     *
+     * @param o
+     * @return
+     */
+    public static String digest(Object... o) throws NoSuchAlgorithmException {
+        StringJoiner stringJoiner = new StringJoiner("");
+        if (Objects.nonNull(o) && o.length > 0) {
+            for (int i = 0; i < o.length; i++) {
+                stringJoiner.add(String.valueOf(o[i]));
+            }
+        }
+        return MD5Util.encoder(stringJoiner.toString());
+    }
+}

+ 1 - 1
themis-business/src/main/resources/mapper/TBPrivilegeMapper.xml

@@ -17,7 +17,7 @@
                 tbu.id = tbur.user_id
             where
                 tbp.`type` = 'MENU'
-                and tbu.id = 2
+                and tbu.id = #{userId}
             order by
                 tbp.parent_id,
                 tbp.`sequence`

+ 0 - 8
themis-common/src/main/java/com/qmth/themis/common/enums/ExceptionResultEnum.java

@@ -102,15 +102,7 @@ public enum ExceptionResultEnum {
         return code;
     }
 
-    public void setCode(String code) {
-        this.code = code;
-    }
-
     public String getMessage() {
         return message;
     }
-
-    public void setMessage(String message) {
-        this.message = message;
-    }
 }

+ 11 - 1
themis-common/src/main/java/com/qmth/themis/common/enums/Platform.java

@@ -2,7 +2,7 @@ package com.qmth.themis.common.enums;
 
 public enum Platform {
 
-    SERVER, IOS, Android, WAP, Ipad, Windows, Mac;
+    SERVER("Server"), IOS("Phone"), Android("Phone"), WAP("Web"), Ipad("Pad"), Windows("PC"), Mac("PC");
 
     public static Platform findByName(String name) {
         if (name == null) {
@@ -16,6 +16,16 @@ public enum Platform {
         return null;
     }
 
+    private String source;
+
+    Platform(String source) {
+        this.source = source;
+    }
+
+    public String getSource() {
+        return source;
+    }
+
     public boolean equals(String name) {
         return toString().equalsIgnoreCase(name);
     }

+ 1 - 1
themis-common/src/main/java/com/qmth/themis/common/enums/Source.java

@@ -2,7 +2,7 @@ package com.qmth.themis.common.enums;
 
 public enum Source {
 
-    Phone, Client, Pad, Pc;
+    Phone, Client, Pad, PC, Web, Server;
 
     public static Source findByName(String name) {
         if (name == null) {

+ 3 - 2
themis-exam/src/main/java/com/qmth/themis/exam/ThemisExamApplication.java

@@ -13,6 +13,7 @@ import org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfigura
 import org.springframework.cache.annotation.EnableCaching;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Primary;
 import org.springframework.data.redis.connection.RedisConnectionFactory;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
@@ -28,7 +29,6 @@ import org.springframework.web.multipart.commons.CommonsMultipartResolver;
 @MapperScan("com.qmth.themis.business.dao")
 //主要就是定义扫描的路径从中找出标识了需要装配的类自动装配到spring的bean容器中,做过web开发的同学一定都有用过@Controller,@Service,@Repository注解,查看其源码你会发现,他们中有一个共同的注解@Component,没错@ComponentScan注解默认就会装配标识了@Controller,@Service,@Repository,@Component注解的类到spring容器中
 @EntityScan(basePackages = {"com.qmth.themis.business.entity"})//用来扫描和发现指定包及其子包中的Entity定义
-@EnableAutoConfiguration(exclude = {MultipartAutoConfiguration.class})//
 @EnableTransactionManagement //spring开启事务支持
 @EnableScheduling //spring quartz开启
 @EnableAsync //开启异步任务
@@ -44,7 +44,7 @@ public class ThemisExamApplication {
      *
      * @return
      */
-    @Bean(name = "multipartResolver")
+    @Bean
     public MultipartResolver multipartResolver() {
         CommonsMultipartResolver resolver = new CommonsMultipartResolver();
         resolver.setDefaultEncoding(Constants.CHARSET_NAME);
@@ -55,6 +55,7 @@ public class ThemisExamApplication {
     }
 
     @Bean
+    @Primary
     public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
         RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
         template.setConnectionFactory(connectionFactory);

+ 2 - 2
themis-exam/src/main/resources/application.properties

@@ -19,7 +19,7 @@ db.username=root
 db.password=123456789
 #redis\u6570\u636E\u6E90\u914D\u7F6E
 redis.host=${db.host}
-redis.database=0
+redis.database=14
 redis.port=6379
 redis.password=
 spring.datasource.url=jdbc:mysql://${db.host}:${db.port}/${db.name}?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8
@@ -70,7 +70,7 @@ mybatis-plus.mapper-locations=classpath:/mapper/*Mapper.xml
 mybatis-plus.global-config.id-type=1
 mybatis-plus.configuration.map-underscore-to-camel-case=true
 mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
-logging.level.com.qmth.themis.backend.mapper=debug
+logging.level.com.qmth.themis.business.dao=debug
 mybatis-plus.configuration.call-setters-on-nulls=true
 
 #redis