mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 18:49:06 +08:00 
			
		
		
		
	将 LoginUser 重构到 UserSessionService 模块汇总
This commit is contained in:
		
							
								
								
									
										7
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								pom.xml
									
									
									
									
									
								
							| @ -53,7 +53,6 @@ | |||||||
|         <!-- 工具类相关 --> |         <!-- 工具类相关 --> | ||||||
|         <lombok.version>1.16.14</lombok.version> |         <lombok.version>1.16.14</lombok.version> | ||||||
|         <mapstruct.version>1.4.1.Final</mapstruct.version> |         <mapstruct.version>1.4.1.Final</mapstruct.version> | ||||||
|         <jjwt.version>0.9.1</jjwt.version> |  | ||||||
|         <hutool.version>5.5.6</hutool.version> |         <hutool.version>5.5.6</hutool.version> | ||||||
|         <easyexcel.verion>2.2.7</easyexcel.verion> |         <easyexcel.verion>2.2.7</easyexcel.verion> | ||||||
|     </properties> |     </properties> | ||||||
| @ -177,12 +176,6 @@ | |||||||
|             <version>${lombok.version}</version> |             <version>${lombok.version}</version> | ||||||
|         </dependency> |         </dependency> | ||||||
|  |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>io.jsonwebtoken</groupId> |  | ||||||
|             <artifactId>jjwt</artifactId> |  | ||||||
|             <version>${jjwt.version}</version> |  | ||||||
|         </dependency> |  | ||||||
|  |  | ||||||
|         <dependency> |         <dependency> | ||||||
|             <groupId>org.projectlombok</groupId> |             <groupId>org.projectlombok</groupId> | ||||||
|             <artifactId>lombok</artifactId> |             <artifactId>lombok</artifactId> | ||||||
|  | |||||||
| @ -1,30 +0,0 @@ | |||||||
| package com.ruoyi; |  | ||||||
|  |  | ||||||
| import org.springframework.boot.SpringApplication; |  | ||||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; |  | ||||||
| import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * 启动程序 |  | ||||||
|  *  |  | ||||||
|  * @author ruoyi |  | ||||||
|  */ |  | ||||||
| @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) |  | ||||||
| public class RuoYiApplication |  | ||||||
| { |  | ||||||
|     public static void main(String[] args) |  | ||||||
|     { |  | ||||||
|         // System.setProperty("spring.devtools.restart.enabled", "false"); |  | ||||||
|         SpringApplication.run(RuoYiApplication.class, args); |  | ||||||
|         System.out.println("(♥◠‿◠)ノ゙  若依启动成功   ლ(´ڡ`ლ)゙  \n" + |  | ||||||
|                 " .-------.       ____     __        \n" + |  | ||||||
|                 " |  _ _   \\      \\   \\   /  /    \n" + |  | ||||||
|                 " | ( ' )  |       \\  _. /  '       \n" + |  | ||||||
|                 " |(_ o _) /        _( )_ .'         \n" + |  | ||||||
|                 " | (_,_).' __  ___(_ o _)'          \n" + |  | ||||||
|                 " |  |\\ \\  |  ||   |(_,_)'         \n" + |  | ||||||
|                 " |  | \\ `'   /|   `-'  /           \n" + |  | ||||||
|                 " |  |  \\    /  \\      /           \n" + |  | ||||||
|                 " ''-'   `'-'    `-..-'              "); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,92 +0,0 @@ | |||||||
| package com.ruoyi.web.controller.monitor; |  | ||||||
|  |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.Collection; |  | ||||||
| import java.util.Collections; |  | ||||||
| import java.util.List; |  | ||||||
| import org.springframework.beans.factory.annotation.Autowired; |  | ||||||
| import org.springframework.security.access.prepost.PreAuthorize; |  | ||||||
| import org.springframework.web.bind.annotation.DeleteMapping; |  | ||||||
| import org.springframework.web.bind.annotation.GetMapping; |  | ||||||
| import org.springframework.web.bind.annotation.PathVariable; |  | ||||||
| import org.springframework.web.bind.annotation.RequestMapping; |  | ||||||
| import org.springframework.web.bind.annotation.RestController; |  | ||||||
| import com.ruoyi.common.annotation.Log; |  | ||||||
| import com.ruoyi.common.constant.Constants; |  | ||||||
| import com.ruoyi.common.core.controller.BaseController; |  | ||||||
| import com.ruoyi.common.core.domain.AjaxResult; |  | ||||||
| import com.ruoyi.common.core.domain.model.LoginUser; |  | ||||||
| import com.ruoyi.common.core.page.TableDataInfo; |  | ||||||
| import com.ruoyi.common.core.redis.RedisCache; |  | ||||||
| import com.ruoyi.common.enums.BusinessType; |  | ||||||
| import com.ruoyi.common.utils.StringUtils; |  | ||||||
| import com.ruoyi.system.domain.SysUserOnline; |  | ||||||
| import com.ruoyi.system.service.ISysUserOnlineService; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * 在线用户监控 |  | ||||||
|  *  |  | ||||||
|  * @author ruoyi |  | ||||||
|  */ |  | ||||||
| @RestController |  | ||||||
| @RequestMapping("/monitor/online") |  | ||||||
| public class SysUserOnlineController extends BaseController |  | ||||||
| { |  | ||||||
|     @Autowired |  | ||||||
|     private ISysUserOnlineService userOnlineService; |  | ||||||
|  |  | ||||||
|     @Autowired |  | ||||||
|     private RedisCache redisCache; |  | ||||||
|  |  | ||||||
|     @PreAuthorize("@ss.hasPermi('monitor:online:list')") |  | ||||||
|     @GetMapping("/list") |  | ||||||
|     public TableDataInfo list(String ipaddr, String userName) |  | ||||||
|     { |  | ||||||
|         Collection<String> keys = redisCache.keys(Constants.LOGIN_TOKEN_KEY + "*"); |  | ||||||
|         List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>(); |  | ||||||
|         for (String key : keys) |  | ||||||
|         { |  | ||||||
|             LoginUser user = redisCache.getCacheObject(key); |  | ||||||
|             if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) |  | ||||||
|             { |  | ||||||
|                 if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) |  | ||||||
|                 { |  | ||||||
|                     userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user)); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             else if (StringUtils.isNotEmpty(ipaddr)) |  | ||||||
|             { |  | ||||||
|                 if (StringUtils.equals(ipaddr, user.getIpaddr())) |  | ||||||
|                 { |  | ||||||
|                     userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user)); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser())) |  | ||||||
|             { |  | ||||||
|                 if (StringUtils.equals(userName, user.getUsername())) |  | ||||||
|                 { |  | ||||||
|                     userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user)); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             else |  | ||||||
|             { |  | ||||||
|                 userOnlineList.add(userOnlineService.loginUserToUserOnline(user)); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         Collections.reverse(userOnlineList); |  | ||||||
|         userOnlineList.removeAll(Collections.singleton(null)); |  | ||||||
|         return getDataTable(userOnlineList); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 强退用户 |  | ||||||
|      */ |  | ||||||
|     @PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')") |  | ||||||
|     @Log(title = "在线用户", businessType = BusinessType.FORCE) |  | ||||||
|     @DeleteMapping("/{tokenId}") |  | ||||||
|     public AjaxResult forceLogout(@PathVariable String tokenId) |  | ||||||
|     { |  | ||||||
|         redisCache.deleteObject(Constants.LOGIN_TOKEN_KEY + tokenId); |  | ||||||
|         return AjaxResult.success(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1 +0,0 @@ | |||||||
| restart.include.json=/com.alibaba.fastjson.*.jar |  | ||||||
| @ -34,20 +34,6 @@ logging: | |||||||
|     com.ruoyi: debug |     com.ruoyi: debug | ||||||
|     org.springframework: warn |     org.springframework: warn | ||||||
|  |  | ||||||
| # Spring配置 |  | ||||||
| spring: |  | ||||||
|   # 资源信息 |  | ||||||
|   messages: |  | ||||||
|     # 国际化资源文件路径 |  | ||||||
|     basename: i18n/messages |  | ||||||
|   profiles: |  | ||||||
|     active: druid |  | ||||||
|   # 服务模块 |  | ||||||
|   devtools: |  | ||||||
|     restart: |  | ||||||
|       # 热部署开关 |  | ||||||
|       enabled: true |  | ||||||
|  |  | ||||||
| # 防止XSS攻击 | # 防止XSS攻击 | ||||||
| xss: | xss: | ||||||
|   # 过滤开关 |   # 过滤开关 | ||||||
|  | |||||||
| @ -34,7 +34,4 @@ public class BaseDO implements Serializable { | |||||||
|     @TableLogic |     @TableLogic | ||||||
|     private Integer deleted; |     private Integer deleted; | ||||||
|  |  | ||||||
| //    /** 备注 */ TODO 思考下,怎么解决 |  | ||||||
| //    private String remark; |  | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -28,6 +28,8 @@ import java.util.List; | |||||||
| import static cn.iocoder.dashboard.common.pojo.CommonResult.success; | import static cn.iocoder.dashboard.common.pojo.CommonResult.success; | ||||||
| import static cn.iocoder.dashboard.framework.security.core.util.SecurityUtils.getLoginUserId; | import static cn.iocoder.dashboard.framework.security.core.util.SecurityUtils.getLoginUserId; | ||||||
| import static cn.iocoder.dashboard.framework.security.core.util.SecurityUtils.getLoginUserRoleIds; | import static cn.iocoder.dashboard.framework.security.core.util.SecurityUtils.getLoginUserRoleIds; | ||||||
|  | import static cn.iocoder.dashboard.util.servlet.ServletUtils.getClientIP; | ||||||
|  | import static cn.iocoder.dashboard.util.servlet.ServletUtils.getUserAgent; | ||||||
|  |  | ||||||
| @Api("认证 API") | @Api("认证 API") | ||||||
| @RestController | @RestController | ||||||
| @ -47,7 +49,7 @@ public class SysAuthController { | |||||||
|     @PostMapping("/login") |     @PostMapping("/login") | ||||||
|     @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 |     @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 | ||||||
|     public CommonResult<SysAuthLoginRespVO> login(@RequestBody @Valid SysAuthLoginReqVO reqVO) { |     public CommonResult<SysAuthLoginRespVO> login(@RequestBody @Valid SysAuthLoginReqVO reqVO) { | ||||||
|         String token = authService.login(reqVO.getUsername(), reqVO.getPassword(), reqVO.getUuid(), reqVO.getCode()); |         String token = authService.login(reqVO, getClientIP(), getUserAgent()); | ||||||
|         // 返回结果 |         // 返回结果 | ||||||
|         return success(SysAuthLoginRespVO.builder().token(token).build()); |         return success(SysAuthLoginRespVO.builder().token(token).build()); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -0,0 +1,49 @@ | |||||||
|  | package cn.iocoder.dashboard.modules.system.controller.auth; | ||||||
|  |  | ||||||
|  | import cn.iocoder.dashboard.common.pojo.CommonResult; | ||||||
|  | import cn.iocoder.dashboard.common.pojo.PageResult; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.auth.vo.session.SysUserSessionPageItemRespVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.auth.vo.session.SysUserSessionPageReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.auth.SysUserSessionDO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.service.auth.SysUserSessionService; | ||||||
|  | import io.swagger.annotations.Api; | ||||||
|  | import io.swagger.annotations.ApiImplicitParam; | ||||||
|  | import io.swagger.annotations.ApiOperation; | ||||||
|  | import org.springframework.security.access.prepost.PreAuthorize; | ||||||
|  | import org.springframework.validation.annotation.Validated; | ||||||
|  | import org.springframework.web.bind.annotation.*; | ||||||
|  |  | ||||||
|  | import javax.annotation.Resource; | ||||||
|  |  | ||||||
|  | import static cn.iocoder.dashboard.common.pojo.CommonResult.success; | ||||||
|  |  | ||||||
|  | @Api("用户 Session API") | ||||||
|  | @RestController | ||||||
|  | @RequestMapping("/user-session") | ||||||
|  | public class SysUserSessionController { | ||||||
|  |  | ||||||
|  |     @Resource | ||||||
|  |     private SysUserSessionService userSessionService; | ||||||
|  |  | ||||||
|  |     @ApiOperation("获得 Session 分页列表") | ||||||
|  |     @PreAuthorize("@ss.hasPermission('system:user-session:page')") | ||||||
|  |     @GetMapping("/page") | ||||||
|  |     public CommonResult<PageResult<SysUserSessionPageItemRespVO>> getUserSessionPage(@Validated SysUserSessionPageReqVO reqVO) { | ||||||
|  |         // 获得 Session 分页 | ||||||
|  |         PageResult<SysUserSessionDO> sessionPage = userSessionService.getUserSessionPage(reqVO); | ||||||
|  |  | ||||||
|  |         // | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @ApiOperation("删除 Session") | ||||||
|  |     @PreAuthorize("@ss.hasPermission('system:user-session:delete')") | ||||||
|  |     @DeleteMapping("/delete") | ||||||
|  |     @ApiImplicitParam(name = "id", value = "Session 编号", required = true, dataTypeClass = String.class, | ||||||
|  |             example = "fe50b9f6-d177-44b1-8da9-72ea34f63db7") | ||||||
|  |     public CommonResult<Boolean> delete(@RequestParam("id") String id) { | ||||||
|  |         userSessionService.deleteUserSession(id); | ||||||
|  |         return success(true); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -0,0 +1,36 @@ | |||||||
|  | package cn.iocoder.dashboard.modules.system.controller.auth.vo.session; | ||||||
|  |  | ||||||
|  | import cn.iocoder.dashboard.common.pojo.PageParam; | ||||||
|  | import io.swagger.annotations.ApiModel; | ||||||
|  | import io.swagger.annotations.ApiModelProperty; | ||||||
|  | import lombok.AllArgsConstructor; | ||||||
|  | import lombok.Data; | ||||||
|  | import lombok.EqualsAndHashCode; | ||||||
|  | import lombok.NoArgsConstructor; | ||||||
|  |  | ||||||
|  | @ApiModel(value = "用户在线 Session Response VO", description = "相比用户基本信息来说,会多部门、用户账号等信息") | ||||||
|  | @Data | ||||||
|  | @NoArgsConstructor | ||||||
|  | @AllArgsConstructor | ||||||
|  | @EqualsAndHashCode(callSuper = true) | ||||||
|  | public class SysUserSessionPageItemRespVO extends PageParam { | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "Session 编号", required = true, example = "fe50b9f6-d177-44b1-8da9-72ea34f63db7") | ||||||
|  |     private String id; | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "用户 IP", required = true, example = "127.0.0.1") | ||||||
|  |     private String userIp; | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "浏览器 UserAgent", required = true, example = "Mozilla/5.0") | ||||||
|  |     private String userAgent; | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "登陆时间", required = true) | ||||||
|  |     private String createTime; | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "用户账号", required = true, example = "yudao") | ||||||
|  |     private String username; | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "部门名称", example = "研发部") | ||||||
|  |     private String deptName; | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -2,11 +2,22 @@ package cn.iocoder.dashboard.modules.system.controller.auth.vo.session; | |||||||
|  |  | ||||||
| import cn.iocoder.dashboard.common.pojo.PageParam; | import cn.iocoder.dashboard.common.pojo.PageParam; | ||||||
| import io.swagger.annotations.ApiModel; | import io.swagger.annotations.ApiModel; | ||||||
|  | import io.swagger.annotations.ApiModelProperty; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
| import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||||
|  |  | ||||||
|  | import javax.validation.constraints.NotEmpty; | ||||||
|  |  | ||||||
| @ApiModel("在线用户 Session 分页 Request VO") | @ApiModel("在线用户 Session 分页 Request VO") | ||||||
| @Data | @Data | ||||||
| @EqualsAndHashCode(callSuper = true) | @EqualsAndHashCode(callSuper = true) | ||||||
| public class SysUserSessionPageReqVO extends PageParam { | public class SysUserSessionPageReqVO extends PageParam { | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "用户 IP", example = "127.0.0.1", notes = "模糊匹配") | ||||||
|  |     @NotEmpty(message = "用户 IP 不能为空") | ||||||
|  |     private String userIp; | ||||||
|  |  | ||||||
|  |     @ApiModelProperty(value = "用户账号", example = "yudao", notes = "模糊匹配") | ||||||
|  |     private String username; | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -2,6 +2,8 @@ package cn.iocoder.dashboard.modules.system.dal.mysql.dao.auth; | |||||||
| 
 | 
 | ||||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.auth.SysUserSessionDO; | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.auth.SysUserSessionDO; | ||||||
| import com.baomidou.mybatisplus.core.mapper.BaseMapper; | import com.baomidou.mybatisplus.core.mapper.BaseMapper; | ||||||
|  | import org.apache.ibatis.annotations.Mapper; | ||||||
| 
 | 
 | ||||||
| public interface SysUserOnlineMapper extends BaseMapper<SysUserSessionDO> { | @Mapper | ||||||
|  | public interface SysUserSessionMapper extends BaseMapper<SysUserSessionDO> { | ||||||
| } | } | ||||||
| @ -1,17 +1,26 @@ | |||||||
| package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.auth; | package cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.auth; | ||||||
|  |  | ||||||
| import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; | import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; | ||||||
|  | import cn.iocoder.dashboard.framework.security.core.LoginUser; | ||||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; | ||||||
| import com.baomidou.mybatisplus.annotation.TableId; | import com.baomidou.mybatisplus.annotation.TableId; | ||||||
| import com.baomidou.mybatisplus.annotation.TableName; | import com.baomidou.mybatisplus.annotation.TableName; | ||||||
|  | import lombok.Builder; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
| import lombok.EqualsAndHashCode; | import lombok.EqualsAndHashCode; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 在线用户表 |  * 在线用户表 | ||||||
|  |  * | ||||||
|  |  * 我们已经将 {@link LoginUser} 缓存在 Redis 当中。 | ||||||
|  |  * 这里额外存储在线用户到 MySQL 中,目的是为了方便管理界面可以灵活查询。 | ||||||
|  |  * 同时,通过定时轮询 SysUserSessionDO 表,可以主动删除 Redis 的缓存,因为 Redis 的过期删除是延迟的。 | ||||||
|  |  * | ||||||
|  |  * @author 芋道源码 | ||||||
|  */ |  */ | ||||||
| @TableName(value = "sys_user_session", autoResultMap = true) | @TableName(value = "sys_user_session", autoResultMap = true) | ||||||
| @Data | @Data | ||||||
|  | @Builder | ||||||
| @EqualsAndHashCode(callSuper = true) | @EqualsAndHashCode(callSuper = true) | ||||||
| public class SysUserSessionDO extends BaseDO { | public class SysUserSessionDO extends BaseDO { | ||||||
|  |  | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| package cn.iocoder.dashboard.modules.system.service.auth; | package cn.iocoder.dashboard.modules.system.service.auth; | ||||||
|  |  | ||||||
| import cn.iocoder.dashboard.framework.security.core.service.SecurityAuthFrameworkService; | import cn.iocoder.dashboard.framework.security.core.service.SecurityAuthFrameworkService; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthLoginReqVO; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 认证 Service 接口 |  * 认证 Service 接口 | ||||||
| @ -11,6 +12,14 @@ import cn.iocoder.dashboard.framework.security.core.service.SecurityAuthFramewor | |||||||
|  */ |  */ | ||||||
| public interface SysAuthService extends SecurityAuthFrameworkService { | public interface SysAuthService extends SecurityAuthFrameworkService { | ||||||
|  |  | ||||||
|     String login(String username, String password, String captchaUUID, String captchaCode); |     /** | ||||||
|  |      * 登陆用户 | ||||||
|  |      * | ||||||
|  |      * @param reqVO 登陆信息 | ||||||
|  |      * @param userIp 用户 IP | ||||||
|  |      * @param userAgent 用户 UA | ||||||
|  |      * @return 身份令牌,使用 JWT 方式 | ||||||
|  |      */ | ||||||
|  |     String login(SysAuthLoginReqVO reqVO, String userIp, String userAgent); | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,30 +0,0 @@ | |||||||
| package cn.iocoder.dashboard.modules.system.service.auth; |  | ||||||
|  |  | ||||||
| import io.jsonwebtoken.Claims; |  | ||||||
|  |  | ||||||
| import java.util.Map; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Token Service 接口 |  | ||||||
|  * |  | ||||||
|  * 提供访问 Token 令牌,目前基于 JWT 实现 |  | ||||||
|  */ |  | ||||||
| public interface SysTokenService { |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 创建 Token |  | ||||||
|      * |  | ||||||
|      * @param subject 主体 |  | ||||||
|      * @return Token 字符串 |  | ||||||
|      */ |  | ||||||
|     String createToken(String subject); |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 解析 Token,返回 claims 数据声明 |  | ||||||
|      * |  | ||||||
|      * @param token Token |  | ||||||
|      * @return claims |  | ||||||
|      */ |  | ||||||
|     Claims parseToken(String token); |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @ -1,40 +0,0 @@ | |||||||
| package cn.iocoder.dashboard.modules.system.service.auth; |  | ||||||
|  |  | ||||||
| import cn.iocoder.dashboard.common.pojo.PageResult; |  | ||||||
| import cn.iocoder.dashboard.modules.system.controller.auth.vo.session.SysUserSessionPageReqVO; |  | ||||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.auth.SysUserSessionDO; |  | ||||||
|  |  | ||||||
| import java.util.Date; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * 在线用户 Session Service 接口 |  | ||||||
|  */ |  | ||||||
| public interface SysUserOnlineService { |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 创建在线用户 Session |  | ||||||
|      * |  | ||||||
|      * @param sessionId Session 编号 |  | ||||||
|      * @param userId 用户编号 |  | ||||||
|      * @param userIp 用户 IP |  | ||||||
|      * @param userAgent 用户 UA |  | ||||||
|      */ |  | ||||||
|     void createUserOnline(String sessionId, Long userId, String userIp, String userAgent); |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 更新在线用户 Session 的更新时间 |  | ||||||
|      * |  | ||||||
|      * @param sessionId Session 编号 |  | ||||||
|      * @param updateTime 更新时间 |  | ||||||
|      */ |  | ||||||
|     void updateUserOnlineUpdateTime(String sessionId, Date updateTime); |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * 获得在线用户分页列表 |  | ||||||
|      * |  | ||||||
|      * @param reqVO 分页条件 |  | ||||||
|      * @return 份额与列表 |  | ||||||
|      */ |  | ||||||
|     PageResult<SysUserSessionDO> getUserSessionPage(SysUserSessionPageReqVO reqVO); |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @ -0,0 +1,63 @@ | |||||||
|  | package cn.iocoder.dashboard.modules.system.service.auth; | ||||||
|  |  | ||||||
|  | import cn.iocoder.dashboard.common.pojo.PageResult; | ||||||
|  | import cn.iocoder.dashboard.framework.security.core.LoginUser; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.auth.vo.session.SysUserSessionPageReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.auth.SysUserSessionDO; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 在线用户 Session Service 接口 | ||||||
|  |  * | ||||||
|  |  * @author 芋道源码 | ||||||
|  |  */ | ||||||
|  | public interface SysUserSessionService { | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 创建在线用户 Session | ||||||
|  |      * | ||||||
|  |      * @param loginUser 登陆用户 | ||||||
|  |      * @param userIp 用户 IP | ||||||
|  |      * @param userAgent 用户 UA | ||||||
|  |      * @return Session 编号 | ||||||
|  |      */ | ||||||
|  |     String createUserSession(LoginUser loginUser, String userIp, String userAgent); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 刷新在线用户 Session 的更新时间 | ||||||
|  |      * | ||||||
|  |      * @param sessionId Session 编号 | ||||||
|  |      * @param loginUser 登陆用户 | ||||||
|  |      */ | ||||||
|  |     void refreshUserSession(String sessionId, LoginUser loginUser); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 删除在线用户 Session | ||||||
|  |      * | ||||||
|  |      * @param sessionId Session 编号 | ||||||
|  |      */ | ||||||
|  |     void deleteUserSession(String sessionId); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 获得 Session 编号对应的在线用户 | ||||||
|  |      * | ||||||
|  |      * @param sessionId Session 编号 | ||||||
|  |      * @return 在线用户 | ||||||
|  |      */ | ||||||
|  |     LoginUser getLoginUser(String sessionId); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 获得 Session 超时时间,单位:毫秒 | ||||||
|  |      * | ||||||
|  |      * @return 超时时间 | ||||||
|  |      */ | ||||||
|  |     Long getSessionTimeoutMillis(); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 获得在线用户分页列表 | ||||||
|  |      * | ||||||
|  |      * @param reqVO 分页条件 | ||||||
|  |      * @return 份额与列表 | ||||||
|  |      */ | ||||||
|  |     PageResult<SysUserSessionDO> getUserSessionPage(SysUserSessionPageReqVO reqVO); | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -1,28 +1,22 @@ | |||||||
| package cn.iocoder.dashboard.modules.system.service.auth.impl; | package cn.iocoder.dashboard.modules.system.service.auth.impl; | ||||||
|  |  | ||||||
| import cn.hutool.core.util.IdUtil; |  | ||||||
| import cn.hutool.core.util.StrUtil; |  | ||||||
| import cn.iocoder.dashboard.common.enums.CommonStatusEnum; | import cn.iocoder.dashboard.common.enums.CommonStatusEnum; | ||||||
| import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil; | import cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil; | ||||||
| import cn.iocoder.dashboard.framework.security.config.SecurityProperties; |  | ||||||
| import cn.iocoder.dashboard.framework.security.core.LoginUser; | import cn.iocoder.dashboard.framework.security.core.LoginUser; | ||||||
| import cn.iocoder.dashboard.framework.tracer.core.util.TracerUtils; | import cn.iocoder.dashboard.framework.tracer.core.util.TracerUtils; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.auth.vo.auth.SysAuthLoginReqVO; | ||||||
| import cn.iocoder.dashboard.modules.system.controller.logger.vo.loginlog.SysLoginLogCreateReqVO; | import cn.iocoder.dashboard.modules.system.controller.logger.vo.loginlog.SysLoginLogCreateReqVO; | ||||||
| import cn.iocoder.dashboard.modules.system.convert.auth.SysAuthConvert; | import cn.iocoder.dashboard.modules.system.convert.auth.SysAuthConvert; | ||||||
| import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.user.SysUserDO; | ||||||
| import cn.iocoder.dashboard.modules.system.dal.redis.dao.auth.SysLoginUserRedisDAO; |  | ||||||
| import cn.iocoder.dashboard.modules.system.enums.logger.SysLoginLogTypeEnum; | import cn.iocoder.dashboard.modules.system.enums.logger.SysLoginLogTypeEnum; | ||||||
| import cn.iocoder.dashboard.modules.system.enums.logger.SysLoginResultEnum; | import cn.iocoder.dashboard.modules.system.enums.logger.SysLoginResultEnum; | ||||||
| import cn.iocoder.dashboard.modules.system.service.auth.SysAuthService; | import cn.iocoder.dashboard.modules.system.service.auth.SysAuthService; | ||||||
| import cn.iocoder.dashboard.modules.system.service.auth.SysTokenService; | import cn.iocoder.dashboard.modules.system.service.auth.SysUserSessionService; | ||||||
| import cn.iocoder.dashboard.modules.system.service.common.SysCaptchaService; | import cn.iocoder.dashboard.modules.system.service.common.SysCaptchaService; | ||||||
| import cn.iocoder.dashboard.modules.system.service.logger.SysLoginLogService; | import cn.iocoder.dashboard.modules.system.service.logger.SysLoginLogService; | ||||||
| import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService; | import cn.iocoder.dashboard.modules.system.service.permission.SysPermissionService; | ||||||
| import cn.iocoder.dashboard.modules.system.service.user.SysUserService; | import cn.iocoder.dashboard.modules.system.service.user.SysUserService; | ||||||
| import cn.iocoder.dashboard.util.date.DateUtils; |  | ||||||
| import cn.iocoder.dashboard.util.servlet.ServletUtils; | import cn.iocoder.dashboard.util.servlet.ServletUtils; | ||||||
| import io.jsonwebtoken.Claims; |  | ||||||
| import io.jsonwebtoken.JwtException; |  | ||||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||||
| import org.springframework.security.authentication.AuthenticationManager; | import org.springframework.security.authentication.AuthenticationManager; | ||||||
| import org.springframework.security.authentication.BadCredentialsException; | import org.springframework.security.authentication.BadCredentialsException; | ||||||
| @ -37,7 +31,6 @@ import org.springframework.util.Assert; | |||||||
|  |  | ||||||
| import javax.annotation.Resource; | import javax.annotation.Resource; | ||||||
| import java.util.Collections; | import java.util.Collections; | ||||||
| import java.util.Date; |  | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
|  |  | ||||||
| import static cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil.exception; | import static cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil.exception; | ||||||
| @ -52,11 +45,6 @@ import static cn.iocoder.dashboard.modules.system.enums.SysErrorCodeConstants.*; | |||||||
| @Slf4j | @Slf4j | ||||||
| public class SysAuthServiceImpl implements SysAuthService { | public class SysAuthServiceImpl implements SysAuthService { | ||||||
|  |  | ||||||
|     @Resource |  | ||||||
|     private SecurityProperties securityProperties; |  | ||||||
|  |  | ||||||
|     @Resource |  | ||||||
|     private SysTokenService tokenService; |  | ||||||
|     @Resource |     @Resource | ||||||
|     private AuthenticationManager authenticationManager; |     private AuthenticationManager authenticationManager; | ||||||
|     @Resource |     @Resource | ||||||
| @ -67,9 +55,8 @@ public class SysAuthServiceImpl implements SysAuthService { | |||||||
|     private SysCaptchaService captchaService; |     private SysCaptchaService captchaService; | ||||||
|     @Resource |     @Resource | ||||||
|     private SysLoginLogService loginLogService; |     private SysLoginLogService loginLogService; | ||||||
|  |  | ||||||
|     @Resource |     @Resource | ||||||
|     private SysLoginUserRedisDAO loginUserRedisDAO; |     private SysUserSessionService userSessionService; | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { |     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { | ||||||
| @ -91,27 +78,21 @@ public class SysAuthServiceImpl implements SysAuthService { | |||||||
|         } |         } | ||||||
|         // 创建 LoginUser 对象 |         // 创建 LoginUser 对象 | ||||||
|         LoginUser loginUser = SysAuthConvert.INSTANCE.convert(user); |         LoginUser loginUser = SysAuthConvert.INSTANCE.convert(user); | ||||||
|         loginUser.setUpdateTime(new Date()); |         loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId())); // 获取用户角色列表 | ||||||
|         loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId())); |  | ||||||
|         return loginUser; |         return loginUser; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public String login(String username, String password, String captchaUUID, String captchaCode) { |     public String login(SysAuthLoginReqVO reqVO, String userIp, String userAgent) { | ||||||
|         // 判断验证码是否正确 |         // 判断验证码是否正确 | ||||||
|         this.verifyCaptcha(username, captchaUUID, captchaCode); |         this.verifyCaptcha(reqVO.getUsername(), reqVO.getUuid(), reqVO.getCode()); | ||||||
|  |  | ||||||
|         // 使用账号密码,进行登陆。 |         // 使用账号密码,进行登陆。 | ||||||
|         LoginUser loginUser = this.login0(username, password); |         LoginUser loginUser = this.login0(reqVO.getUsername(), reqVO.getPassword()); | ||||||
|         // 缓存登陆用户到 Redis 中 |         loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId())); // 获取用户角色列表 | ||||||
|         String sessionId = IdUtil.fastSimpleUUID(); |  | ||||||
|         loginUser.setUpdateTime(new Date()); |  | ||||||
|         loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId())); |  | ||||||
|         loginUserRedisDAO.set(sessionId, loginUser); |  | ||||||
|  |  | ||||||
|         // 创建 Token |         // 缓存登陆用户到 Redis 中,返回 sessionId 编号 | ||||||
|         // 我们在返回给前端的 JWT 中,使用 sessionId 作为 subject 主体,标识当前 User 用户 |         return userSessionService.createUserSession(loginUser, userIp, userAgent); | ||||||
|         return tokenService.createToken(sessionId); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void verifyCaptcha(String username, String captchaUUID, String captchaCode) { |     private void verifyCaptcha(String username, String captchaUUID, String captchaCode) { | ||||||
| @ -182,42 +163,20 @@ public class SysAuthServiceImpl implements SysAuthService { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public LoginUser verifyTokenAndRefresh(String token) { |     public LoginUser verifyTokenAndRefresh(String token) { | ||||||
|         // 验证 token 的有效性 |  | ||||||
|         String sessionId = this.verifyToken(token); |  | ||||||
|         // 获得 LoginUser |         // 获得 LoginUser | ||||||
|         LoginUser loginUser = loginUserRedisDAO.get(sessionId); |         LoginUser loginUser = userSessionService.getLoginUser(token); | ||||||
|         if (loginUser == null) { |         if (loginUser == null) { | ||||||
|             return null; |             return null; | ||||||
|         } |         } | ||||||
|         // 刷新 LoginUser 缓存 |         // 刷新 LoginUser 缓存 | ||||||
|         this.refreshLoginUserCache(sessionId, loginUser); |         this.refreshLoginUserCache(token, loginUser); | ||||||
|         return loginUser; |         return loginUser; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private String verifyToken(String token) { |     private void refreshLoginUserCache(String token, LoginUser loginUser) { | ||||||
|         Claims claims; |  | ||||||
|         try { |  | ||||||
|             claims = tokenService.parseToken(token); |  | ||||||
|         } catch (JwtException jwtException) { |  | ||||||
|             log.warn("[verifyToken][token({}) 解析发生异常]", token); |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
|         // token 已经过期 |  | ||||||
|         if (DateUtils.isExpired(claims.getExpiration())) { |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
|         // 判断 sessionId 是否存在 |  | ||||||
|         String sessionId = claims.getSubject(); |  | ||||||
|         if (StrUtil.isBlank(sessionId)) { |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
|         return sessionId; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private void refreshLoginUserCache(String sessionId, LoginUser loginUser) { |  | ||||||
|         // 每 1/3 的 Session 超时时间,刷新 LoginUser 缓存 |         // 每 1/3 的 Session 超时时间,刷新 LoginUser 缓存 | ||||||
|         if (System.currentTimeMillis() - loginUser.getUpdateTime().getTime() < |         if (System.currentTimeMillis() - loginUser.getUpdateTime().getTime() < | ||||||
|                 securityProperties.getSessionTimeout().toMillis() / 3) { |                 userSessionService.getSessionTimeoutMillis() / 3) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @ -229,9 +188,8 @@ public class SysAuthServiceImpl implements SysAuthService { | |||||||
|  |  | ||||||
|         // 刷新 LoginUser 缓存 |         // 刷新 LoginUser 缓存 | ||||||
|         loginUser.setDeptId(user.getDeptId()); |         loginUser.setDeptId(user.getDeptId()); | ||||||
|         loginUser.setUpdateTime(new Date()); |  | ||||||
|         loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId())); |         loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId())); | ||||||
|         loginUserRedisDAO.set(sessionId, loginUser); |         userSessionService.refreshUserSession(token, loginUser); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,58 +0,0 @@ | |||||||
| package cn.iocoder.dashboard.modules.system.service.auth.impl; |  | ||||||
|  |  | ||||||
| import cn.iocoder.dashboard.framework.security.config.SecurityProperties; |  | ||||||
| import cn.iocoder.dashboard.modules.system.service.auth.SysTokenService; |  | ||||||
| import cn.iocoder.dashboard.util.date.DateUtils; |  | ||||||
| import io.jsonwebtoken.Claims; |  | ||||||
| import io.jsonwebtoken.Jwts; |  | ||||||
| import io.jsonwebtoken.SignatureAlgorithm; |  | ||||||
| import org.springframework.stereotype.Service; |  | ||||||
|  |  | ||||||
| import javax.annotation.Resource; |  | ||||||
| import java.util.HashMap; |  | ||||||
| import java.util.Map; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Token Service 实现类 |  | ||||||
|  * |  | ||||||
|  * @author 芋道源码 |  | ||||||
|  */ |  | ||||||
| @Service |  | ||||||
| public class SysTokenServiceImpl implements SysTokenService { |  | ||||||
|  |  | ||||||
|     @Resource |  | ||||||
|     private SecurityProperties securityProperties; |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public String createToken(String subject) { |  | ||||||
|         return Jwts.builder() |  | ||||||
|                 .signWith(SignatureAlgorithm.HS512, securityProperties.getTokenSecret()) |  | ||||||
|                 .setExpiration(DateUtils.addTime(securityProperties.getTokenTimeout())) |  | ||||||
|                 .setSubject(subject) |  | ||||||
|                 .compact(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public Claims parseToken(String token) { |  | ||||||
|         return Jwts.parser() |  | ||||||
|                 .setSigningKey(securityProperties.getTokenSecret()) |  | ||||||
|                 .parseClaimsJws(token) |  | ||||||
|                 .getBody(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public static void main(String[] args) { |  | ||||||
|         String secret = "abcdefghijklmnopqrstuvwxyz"; |  | ||||||
|         Map<String, Object> map = new HashMap<>(); |  | ||||||
|         map.put("key1", "value1"); |  | ||||||
|         System.out.println(Jwts.builder() |  | ||||||
|                 .signWith(SignatureAlgorithm.HS512, secret) |  | ||||||
|                 .setClaims(map) |  | ||||||
|                 .compact()); |  | ||||||
|  |  | ||||||
|         System.out.println(Jwts.parser() |  | ||||||
|                 .setSigningKey(secret) |  | ||||||
|                 .parseClaimsJws("qyJhbGciOiJIUzUxMiJ9.eyJrZXkxIjoidmFsdWUxIn0.AHWncLRBlJkqrKaoWHZmMgbqYIT7rfLs8KCp9LuC0mdNfnx1xEMm1N9bgcD-0lc5sjySqsKiWzqJ3rpoyUSh0g") |  | ||||||
|                 .getBody()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @ -0,0 +1,89 @@ | |||||||
|  | package cn.iocoder.dashboard.modules.system.service.auth.impl; | ||||||
|  |  | ||||||
|  | import cn.hutool.core.util.IdUtil; | ||||||
|  | import cn.iocoder.dashboard.common.pojo.PageResult; | ||||||
|  | import cn.iocoder.dashboard.framework.security.config.SecurityProperties; | ||||||
|  | import cn.iocoder.dashboard.framework.security.core.LoginUser; | ||||||
|  | import cn.iocoder.dashboard.modules.system.controller.auth.vo.session.SysUserSessionPageReqVO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.dal.mysql.dao.auth.SysUserSessionMapper; | ||||||
|  | import cn.iocoder.dashboard.modules.system.dal.mysql.dataobject.auth.SysUserSessionDO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.dal.redis.dao.auth.SysLoginUserRedisDAO; | ||||||
|  | import cn.iocoder.dashboard.modules.system.service.auth.SysUserSessionService; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  |  | ||||||
|  | import javax.annotation.Resource; | ||||||
|  | import java.util.Date; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 在线用户 Session Service 实现类 | ||||||
|  |  * | ||||||
|  |  * @author 芋道源码 | ||||||
|  |  */ | ||||||
|  | @Service | ||||||
|  | public class SysUserSessionServiceImpl implements SysUserSessionService { | ||||||
|  |  | ||||||
|  |     @Resource | ||||||
|  |     private SecurityProperties securityProperties; | ||||||
|  |  | ||||||
|  |     @Resource | ||||||
|  |     private SysLoginUserRedisDAO loginUserRedisDAO; | ||||||
|  |  | ||||||
|  |     @Resource | ||||||
|  |     private SysUserSessionMapper userSessionMapper; | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String createUserSession(LoginUser loginUser, String userIp, String userAgent) { | ||||||
|  |         // 生成 Session 编号 | ||||||
|  |         String sessionId = generateSessionId(); | ||||||
|  |         // 写入 Redis 缓存 | ||||||
|  |         loginUser.setUpdateTime(new Date()); | ||||||
|  |         loginUserRedisDAO.set(sessionId, loginUser); | ||||||
|  |         // 写入 DB 中 | ||||||
|  |         SysUserSessionDO userSession = SysUserSessionDO.builder().userId(loginUser.getId()) | ||||||
|  |                 .userIp(userIp).userAgent(userAgent).build(); | ||||||
|  |         userSessionMapper.insert(userSession); | ||||||
|  |         // 返回 Session 编号 | ||||||
|  |         return sessionId; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void refreshUserSession(String sessionId, LoginUser loginUser) { | ||||||
|  |         // 写入 Redis 缓存 | ||||||
|  |         loginUser.setUpdateTime(new Date()); | ||||||
|  |         loginUserRedisDAO.set(sessionId, loginUser); | ||||||
|  |         // 更新 DB 中 | ||||||
|  |         SysUserSessionDO updateObj = SysUserSessionDO.builder().id(sessionId).build(); | ||||||
|  |         updateObj.setUpdateTime(new Date()); | ||||||
|  |         userSessionMapper.updateById(updateObj); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void deleteUserSession(String sessionId) { | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public LoginUser getLoginUser(String sessionId) { | ||||||
|  |         return loginUserRedisDAO.get(sessionId); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Long getSessionTimeoutMillis() { | ||||||
|  |         return securityProperties.getSessionTimeout().toMillis(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public PageResult<SysUserSessionDO> getUserSessionPage(SysUserSessionPageReqVO reqVO) { | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 生成 Session 编号,目前采用 UUID 算法 | ||||||
|  |      * | ||||||
|  |      * @return Session 编号 | ||||||
|  |      */ | ||||||
|  |     private static String generateSessionId() { | ||||||
|  |         return IdUtil.fastSimpleUUID(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -41,6 +41,7 @@ spring: | |||||||
|  |  | ||||||
| # 芋道配置项,设置当前项目所有自定义的配置 | # 芋道配置项,设置当前项目所有自定义的配置 | ||||||
| yudao: | yudao: | ||||||
|  |   version: 1.0.0 | ||||||
|   web: |   web: | ||||||
|     api-prefix: /api |     api-prefix: /api | ||||||
|     controller-package: cn.iocoder.dashboard |     controller-package: cn.iocoder.dashboard | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| Application Version: ${ruoyi.version} | 芋道源码 http://www.iocoder.cn | ||||||
|  | Application Version: ${yudao.version} | ||||||
| Spring Boot Version: ${spring-boot.version} | Spring Boot Version: ${spring-boot.version} | ||||||
| //////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////// | ||||||
| //                          _ooOoo_                               // | //                          _ooOoo_                               // | ||||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV