Commit 5cf68961e1a5d7b310e6e9d8b9308c88c254b0dd

Authored by YunaiV
1 parent 6ed62486

1. 修改在线会话的实现

2. 接入到会员管理 OAuth2.0
Showing 28 changed files with 356 additions and 150 deletions
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/SecurityProperties.java
@@ -6,7 +6,6 @@ import org.springframework.validation.annotation.Validated; @@ -6,7 +6,6 @@ import org.springframework.validation.annotation.Validated;
6 6
7 import javax.validation.constraints.NotEmpty; 7 import javax.validation.constraints.NotEmpty;
8 import javax.validation.constraints.NotNull; 8 import javax.validation.constraints.NotNull;
9 -import java.time.Duration;  
10 9
11 @ConfigurationProperties(prefix = "yudao.security") 10 @ConfigurationProperties(prefix = "yudao.security")
12 @Validated 11 @Validated
@@ -18,18 +17,6 @@ public class SecurityProperties { @@ -18,18 +17,6 @@ public class SecurityProperties {
18 */ 17 */
19 @NotEmpty(message = "Token Header 不能为空") 18 @NotEmpty(message = "Token Header 不能为空")
20 private String tokenHeader; 19 private String tokenHeader;
21 - /**  
22 - * Token 过期时间  
23 - */  
24 - @NotNull(message = "Token 过期时间不能为空")  
25 - private Duration tokenTimeout;  
26 - /**  
27 - * Session 过期时间  
28 - *  
29 - * 当 User 用户超过当前时间未操作,则 Session 会过期  
30 - */  
31 - @NotNull(message = "Session 过期时间不能为空")  
32 - private Duration sessionTimeout;  
33 20
34 /** 21 /**
35 * mock 模式的开关 22 * mock 模式的开关
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http
@@ -19,7 +19,7 @@ tenant-id: {{appTenentId}} @@ -19,7 +19,7 @@ tenant-id: {{appTenentId}}
19 } 19 }
20 20
21 ### 请求 /sms-login 接口 => 成功 21 ### 请求 /sms-login 接口 => 成功
22 -POST {{appApi}}/member/sms-login 22 +POST {{appApi}}/member/auth/sms-login
23 Content-Type: application/json 23 Content-Type: application/json
24 tenant-id: {{appTenentId}} 24 tenant-id: {{appTenentId}}
25 25
@@ -29,7 +29,12 @@ tenant-id: {{appTenentId}} @@ -29,7 +29,12 @@ tenant-id: {{appTenentId}}
29 } 29 }
30 30
31 ### 请求 /logout 接口 => 成功 31 ### 请求 /logout 接口 => 成功
32 -POST {{appApi}}/member/logout 32 +POST {{appApi}}/member/auth/logout
33 Content-Type: application/json 33 Content-Type: application/json
34 Authorization: Bearer c1b76bdaf2c146c581caa4d7fd81ee66 34 Authorization: Bearer c1b76bdaf2c146c581caa4d7fd81ee66
35 tenant-id: {{appTenentId}} 35 tenant-id: {{appTenentId}}
  36 +
  37 +### 请求 /auth/refresh-token 接口 => 成功
  38 +POST {{appApi}}/member/auth/refresh-token?refreshToken=bc43d929094849a28b3a69f6e6940d70
  39 +Content-Type: application/json
  40 +tenant-id: {{appTenentId}}
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.member.controller.app.auth; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.member.controller.app.auth;
2 2
3 import cn.hutool.core.util.StrUtil; 3 import cn.hutool.core.util.StrUtil;
4 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 4 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
5 import cn.iocoder.yudao.framework.security.config.SecurityProperties; 6 import cn.iocoder.yudao.framework.security.config.SecurityProperties;
6 import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; 7 import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
7 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; 8 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
@@ -20,8 +21,6 @@ import javax.servlet.http.HttpServletRequest; @@ -20,8 +21,6 @@ import javax.servlet.http.HttpServletRequest;
20 import javax.validation.Valid; 21 import javax.validation.Valid;
21 22
22 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 23 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
23 -import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;  
24 -import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getUserAgent;  
25 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 24 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
26 25
27 @Api(tags = "用户 APP - 认证") 26 @Api(tags = "用户 APP - 认证")
@@ -40,8 +39,7 @@ public class AppAuthController { @@ -40,8 +39,7 @@ public class AppAuthController {
40 @PostMapping("/login") 39 @PostMapping("/login")
41 @ApiOperation("使用手机 + 密码登录") 40 @ApiOperation("使用手机 + 密码登录")
42 public CommonResult<AppAuthLoginRespVO> login(@RequestBody @Valid AppAuthLoginReqVO reqVO) { 41 public CommonResult<AppAuthLoginRespVO> login(@RequestBody @Valid AppAuthLoginReqVO reqVO) {
43 - String token = authService.login(reqVO, getClientIP(), getUserAgent());  
44 - return success(AppAuthLoginRespVO.builder().token(token).build()); 42 + return success(authService.login(reqVO));
45 } 43 }
46 44
47 @PostMapping("/logout") 45 @PostMapping("/logout")
@@ -54,12 +52,20 @@ public class AppAuthController { @@ -54,12 +52,20 @@ public class AppAuthController {
54 return success(true); 52 return success(true);
55 } 53 }
56 54
  55 + @PostMapping("/refresh-token")
  56 + @ApiOperation("刷新令牌")
  57 + @ApiImplicitParam(name = "refreshToken", value = "刷新令牌", required = true, dataTypeClass = String.class)
  58 + @OperateLog(enable = false) // 避免 Post 请求被记录操作日志
  59 + public CommonResult<AppAuthLoginRespVO> refreshToken(@RequestParam("refreshToken") String refreshToken) {
  60 + return success(authService.refreshToken(refreshToken));
  61 + }
  62 +
  63 + // ========== 短信登录相关 ==========
  64 +
57 @PostMapping("/sms-login") 65 @PostMapping("/sms-login")
58 @ApiOperation("使用手机 + 验证码登录") 66 @ApiOperation("使用手机 + 验证码登录")
59 public CommonResult<AppAuthLoginRespVO> smsLogin(@RequestBody @Valid AppAuthSmsLoginReqVO reqVO) { 67 public CommonResult<AppAuthLoginRespVO> smsLogin(@RequestBody @Valid AppAuthSmsLoginReqVO reqVO) {
60 - String token = authService.smsLogin(reqVO, getClientIP(), getUserAgent());  
61 - // 返回结果  
62 - return success(AppAuthLoginRespVO.builder().token(token).build()); 68 + return success(authService.smsLogin(reqVO));
63 } 69 }
64 70
65 @PostMapping("/send-sms-code") 71 @PostMapping("/send-sms-code")
@@ -100,16 +106,14 @@ public class AppAuthController { @@ -100,16 +106,14 @@ public class AppAuthController {
100 106
101 @PostMapping("/social-quick-login") 107 @PostMapping("/social-quick-login")
102 @ApiOperation(value = "社交快捷登录,使用 code 授权码", notes = "适合未登录的用户,但是社交账号已绑定用户") 108 @ApiOperation(value = "社交快捷登录,使用 code 授权码", notes = "适合未登录的用户,但是社交账号已绑定用户")
103 - public CommonResult<AppAuthLoginRespVO> socialLogin(@RequestBody @Valid AppAuthSocialQuickLoginReqVO reqVO) {  
104 - String token = authService.socialQuickLogin(reqVO, getClientIP(), getUserAgent());  
105 - return success(AppAuthLoginRespVO.builder().token(token).build()); 109 + public CommonResult<AppAuthLoginRespVO> socialQuickLogin(@RequestBody @Valid AppAuthSocialQuickLoginReqVO reqVO) {
  110 + return success(authService.socialQuickLogin(reqVO));
106 } 111 }
107 112
108 @PostMapping("/social-bind-login") 113 @PostMapping("/social-bind-login")
109 @ApiOperation(value = "社交绑定登录,使用 手机号 + 手机验证码", notes = "适合未登录的用户,进行登录 + 绑定") 114 @ApiOperation(value = "社交绑定登录,使用 手机号 + 手机验证码", notes = "适合未登录的用户,进行登录 + 绑定")
110 - public CommonResult<AppAuthLoginRespVO> socialLogin2(@RequestBody @Valid AppAuthSocialBindLoginReqVO reqVO) {  
111 - String token = authService.socialBindLogin(reqVO, getClientIP(), getUserAgent());  
112 - return success(AppAuthLoginRespVO.builder().token(token).build()); 115 + public CommonResult<AppAuthLoginRespVO> socialBindLogin(@RequestBody @Valid AppAuthSocialBindLoginReqVO reqVO) {
  116 + return success(authService.socialBindLogin(reqVO));
113 } 117 }
114 118
115 } 119 }
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java
@@ -7,14 +7,25 @@ import lombok.Builder; @@ -7,14 +7,25 @@ import lombok.Builder;
7 import lombok.Data; 7 import lombok.Data;
8 import lombok.NoArgsConstructor; 8 import lombok.NoArgsConstructor;
9 9
10 -@ApiModel("用户 APP - 手机密码登录 Response VO") 10 +import java.util.Date;
  11 +
  12 +@ApiModel("用户 APP - 登录 Response VO")
11 @Data 13 @Data
12 @NoArgsConstructor 14 @NoArgsConstructor
13 @AllArgsConstructor 15 @AllArgsConstructor
14 @Builder 16 @Builder
15 public class AppAuthLoginRespVO { 17 public class AppAuthLoginRespVO {
16 18
17 - @ApiModelProperty(value = "token", required = true, example = "yudaoyuanma")  
18 - private String token; 19 + @ApiModelProperty(value = "用户编号", required = true, example = "1024")
  20 + private Long userId;
  21 +
  22 + @ApiModelProperty(value = "访问令牌", required = true, example = "happy")
  23 + private String accessToken;
  24 +
  25 + @ApiModelProperty(value = "刷新令牌", required = true, example = "nice")
  26 + private String refreshToken;
  27 +
  28 + @ApiModelProperty(value = "过期时间", required = true)
  29 + private Date expiresTime;
19 30
20 } 31 }
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java
1 package cn.iocoder.yudao.module.member.convert.auth; 1 package cn.iocoder.yudao.module.member.convert.auth;
2 2
3 -import cn.iocoder.yudao.framework.security.core.LoginUser;  
4 import cn.iocoder.yudao.module.member.controller.app.auth.vo.*; 3 import cn.iocoder.yudao.module.member.controller.app.auth.vo.*;
5 import cn.iocoder.yudao.module.member.controller.app.social.vo.AppSocialUserUnbindReqVO; 4 import cn.iocoder.yudao.module.member.controller.app.social.vo.AppSocialUserUnbindReqVO;
6 -import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; 5 +import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenRespDTO;
7 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO; 6 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
8 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; 7 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
9 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; 8 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
@@ -17,8 +16,6 @@ public interface AuthConvert { @@ -17,8 +16,6 @@ public interface AuthConvert {
17 16
18 AuthConvert INSTANCE = Mappers.getMapper(AuthConvert.class); 17 AuthConvert INSTANCE = Mappers.getMapper(AuthConvert.class);
19 18
20 - LoginUser convert(MemberUserDO bean);  
21 -  
22 SocialUserBindReqDTO convert(Long userId, Integer userType, AppAuthSocialBindLoginReqVO reqVO); 19 SocialUserBindReqDTO convert(Long userId, Integer userType, AppAuthSocialBindLoginReqVO reqVO);
23 SocialUserBindReqDTO convert(Long userId, Integer userType, AppAuthSocialQuickLoginReqVO reqVO); 20 SocialUserBindReqDTO convert(Long userId, Integer userType, AppAuthSocialQuickLoginReqVO reqVO);
24 SocialUserUnbindReqDTO convert(Long userId, Integer userType, AppSocialUserUnbindReqVO reqVO); 21 SocialUserUnbindReqDTO convert(Long userId, Integer userType, AppSocialUserUnbindReqVO reqVO);
@@ -27,4 +24,6 @@ public interface AuthConvert { @@ -27,4 +24,6 @@ public interface AuthConvert {
27 SmsCodeUseReqDTO convert(AppAuthResetPasswordReqVO reqVO, SmsSceneEnum scene, String usedIp); 24 SmsCodeUseReqDTO convert(AppAuthResetPasswordReqVO reqVO, SmsSceneEnum scene, String usedIp);
28 SmsCodeUseReqDTO convert(AppAuthSmsLoginReqVO reqVO, Integer scene, String usedIp); 25 SmsCodeUseReqDTO convert(AppAuthSmsLoginReqVO reqVO, Integer scene, String usedIp);
29 26
  27 + AppAuthLoginRespVO convert(OAuth2AccessTokenRespDTO bean);
  28 +
30 } 29 }
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthService.java
@@ -17,11 +17,9 @@ public interface MemberAuthService { @@ -17,11 +17,9 @@ public interface MemberAuthService {
17 * 手机 + 密码登录 17 * 手机 + 密码登录
18 * 18 *
19 * @param reqVO 登录信息 19 * @param reqVO 登录信息
20 - * @param userIp 用户 IP  
21 - * @param userAgent 用户 UA  
22 - * @return 身份令牌,使用 JWT 方式 20 + * @return 登录结果
23 */ 21 */
24 - String login(@Valid AppAuthLoginReqVO reqVO, String userIp, String userAgent); 22 + AppAuthLoginRespVO login(@Valid AppAuthLoginReqVO reqVO);
25 23
26 /** 24 /**
27 * 基于 token 退出登录 25 * 基于 token 退出登录
@@ -34,31 +32,25 @@ public interface MemberAuthService { @@ -34,31 +32,25 @@ public interface MemberAuthService {
34 * 手机 + 验证码登陆 32 * 手机 + 验证码登陆
35 * 33 *
36 * @param reqVO 登陆信息 34 * @param reqVO 登陆信息
37 - * @param userIp 用户 IP  
38 - * @param userAgent 用户 UA  
39 - * @return 身份令牌,使用 JWT 方式 35 + * @return 登录结果
40 */ 36 */
41 - String smsLogin(@Valid AppAuthSmsLoginReqVO reqVO, String userIp, String userAgent); 37 + AppAuthLoginRespVO smsLogin(@Valid AppAuthSmsLoginReqVO reqVO);
42 38
43 /** 39 /**
44 * 社交登录,使用 code 授权码 40 * 社交登录,使用 code 授权码
45 * 41 *
46 * @param reqVO 登录信息 42 * @param reqVO 登录信息
47 - * @param userIp 用户 IP  
48 - * @param userAgent 用户 UA  
49 - * @return 身份令牌,使用 JWT 方式 43 + * @return 登录结果
50 */ 44 */
51 - String socialQuickLogin(@Valid AppAuthSocialQuickLoginReqVO reqVO, String userIp, String userAgent); 45 + AppAuthLoginRespVO socialQuickLogin(@Valid AppAuthSocialQuickLoginReqVO reqVO);
52 46
53 /** 47 /**
54 * 社交登录,使用 手机号 + 手机验证码 48 * 社交登录,使用 手机号 + 手机验证码
55 * 49 *
56 * @param reqVO 登录信息 50 * @param reqVO 登录信息
57 - * @param userIp 用户 IP  
58 - * @param userAgent 用户 UA  
59 - * @return 身份令牌,使用 JWT 方式 51 + * @return 登录结果
60 */ 52 */
61 - String socialBindLogin(@Valid AppAuthSocialBindLoginReqVO reqVO, String userIp, String userAgent); 53 + AppAuthLoginRespVO socialBindLogin(@Valid AppAuthSocialBindLoginReqVO reqVO);
62 54
63 /** 55 /**
64 * 获得社交认证 URL 56 * 获得社交认证 URL
@@ -90,4 +82,11 @@ public interface MemberAuthService { @@ -90,4 +82,11 @@ public interface MemberAuthService {
90 */ 82 */
91 void sendSmsCode(Long userId, AppAuthSmsSendReqVO reqVO); 83 void sendSmsCode(Long userId, AppAuthSmsSendReqVO reqVO);
92 84
  85 + /**
  86 + * 刷新访问令牌
  87 + *
  88 + * @param refreshToken 刷新令牌
  89 + * @return 登录结果
  90 + */
  91 + AppAuthLoginRespVO refreshToken(String refreshToken);
93 } 92 }
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java
@@ -6,17 +6,19 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; @@ -6,17 +6,19 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
6 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; 6 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
7 import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; 7 import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
8 import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; 8 import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
9 -import cn.iocoder.yudao.framework.security.core.LoginUser;  
10 import cn.iocoder.yudao.module.member.controller.app.auth.vo.*; 9 import cn.iocoder.yudao.module.member.controller.app.auth.vo.*;
11 import cn.iocoder.yudao.module.member.convert.auth.AuthConvert; 10 import cn.iocoder.yudao.module.member.convert.auth.AuthConvert;
12 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; 11 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
13 import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper; 12 import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
14 import cn.iocoder.yudao.module.member.service.user.MemberUserService; 13 import cn.iocoder.yudao.module.member.service.user.MemberUserService;
15 -import cn.iocoder.yudao.module.system.api.auth.UserSessionApi; 14 +import cn.iocoder.yudao.module.system.api.auth.OAuth2TokenApi;
  15 +import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenCreateReqDTO;
  16 +import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenRespDTO;
16 import cn.iocoder.yudao.module.system.api.logger.LoginLogApi; 17 import cn.iocoder.yudao.module.system.api.logger.LoginLogApi;
17 import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO; 18 import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO;
18 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; 19 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
19 import cn.iocoder.yudao.module.system.api.social.SocialUserApi; 20 import cn.iocoder.yudao.module.system.api.social.SocialUserApi;
  21 +import cn.iocoder.yudao.module.system.enums.auth.OAuth2ClientIdEnum;
20 import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum; 22 import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
21 import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum; 23 import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
22 import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; 24 import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
@@ -49,9 +51,9 @@ public class MemberAuthServiceImpl implements MemberAuthService { @@ -49,9 +51,9 @@ public class MemberAuthServiceImpl implements MemberAuthService {
49 @Resource 51 @Resource
50 private LoginLogApi loginLogApi; 52 private LoginLogApi loginLogApi;
51 @Resource 53 @Resource
52 - private UserSessionApi userSessionApi;  
53 - @Resource  
54 private SocialUserApi socialUserApi; 54 private SocialUserApi socialUserApi;
  55 + @Resource
  56 + private OAuth2TokenApi oauth2TokenApi;
55 57
56 @Resource 58 @Resource
57 private PasswordEncoder passwordEncoder; 59 private PasswordEncoder passwordEncoder;
@@ -59,35 +61,31 @@ public class MemberAuthServiceImpl implements MemberAuthService { @@ -59,35 +61,31 @@ public class MemberAuthServiceImpl implements MemberAuthService {
59 private MemberUserMapper userMapper; 61 private MemberUserMapper userMapper;
60 62
61 @Override 63 @Override
62 - public String login(AppAuthLoginReqVO reqVO, String userIp, String userAgent) { 64 + public AppAuthLoginRespVO login(AppAuthLoginReqVO reqVO) {
63 // 使用手机 + 密码,进行登录。 65 // 使用手机 + 密码,进行登录。
64 - LoginUser loginUser = login0(reqVO.getMobile(), reqVO.getPassword()); 66 + MemberUserDO user = login0(reqVO.getMobile(), reqVO.getPassword());
65 67
66 - // 缓存登录用户到 Redis 中,返回 Token 令牌  
67 - return createUserSessionAfterLoginSuccess(loginUser, reqVO.getMobile(),  
68 - LoginLogTypeEnum.LOGIN_USERNAME, userIp, userAgent); 68 + // 创建 Token 令牌,记录登录日志
  69 + return createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_MOBILE);
69 } 70 }
70 71
71 @Override 72 @Override
72 @Transactional 73 @Transactional
73 - public String smsLogin(AppAuthSmsLoginReqVO reqVO, String userIp, String userAgent) { 74 + public AppAuthLoginRespVO smsLogin(AppAuthSmsLoginReqVO reqVO) {
74 // 校验验证码 75 // 校验验证码
  76 + String userIp = getClientIP();
75 smsCodeApi.useSmsCode(AuthConvert.INSTANCE.convert(reqVO, SmsSceneEnum.MEMBER_LOGIN.getScene(), userIp)); 77 smsCodeApi.useSmsCode(AuthConvert.INSTANCE.convert(reqVO, SmsSceneEnum.MEMBER_LOGIN.getScene(), userIp));
76 78
77 // 获得获得注册用户 79 // 获得获得注册用户
78 MemberUserDO user = userService.createUserIfAbsent(reqVO.getMobile(), userIp); 80 MemberUserDO user = userService.createUserIfAbsent(reqVO.getMobile(), userIp);
79 Assert.notNull(user, "获取用户失败,结果为空"); 81 Assert.notNull(user, "获取用户失败,结果为空");
80 82
81 - // 执行登陆  
82 - LoginUser loginUser = buildLoginUser(user);  
83 -  
84 - // 缓存登录用户到 Redis 中,返回 Token 令牌  
85 - return createUserSessionAfterLoginSuccess(loginUser, reqVO.getMobile(),  
86 - LoginLogTypeEnum.LOGIN_SMS, userIp, userAgent); 83 + // 创建 Token 令牌,记录登录日志
  84 + return createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_SMS);
87 } 85 }
88 86
89 @Override 87 @Override
90 - public String socialQuickLogin(AppAuthSocialQuickLoginReqVO reqVO, String userIp, String userAgent) { 88 + public AppAuthLoginRespVO socialQuickLogin(AppAuthSocialQuickLoginReqVO reqVO) {
91 // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号 89 // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号
92 Long userId = socialUserApi.getBindUserId(UserTypeEnum.MEMBER.getValue(), reqVO.getType(), 90 Long userId = socialUserApi.getBindUserId(UserTypeEnum.MEMBER.getValue(), reqVO.getType(),
93 reqVO.getCode(), reqVO.getState()); 91 reqVO.getCode(), reqVO.getState());
@@ -101,33 +99,30 @@ public class MemberAuthServiceImpl implements MemberAuthService { @@ -101,33 +99,30 @@ public class MemberAuthServiceImpl implements MemberAuthService {
101 throw exception(USER_NOT_EXISTS); 99 throw exception(USER_NOT_EXISTS);
102 } 100 }
103 101
104 - // 创建 LoginUser 对象  
105 - LoginUser loginUser = buildLoginUser(user);  
106 -  
107 - // 缓存登录用户到 Redis 中,返回 Token 令牌  
108 - return createUserSessionAfterLoginSuccess(loginUser, null,  
109 - LoginLogTypeEnum.LOGIN_SOCIAL, userIp, userAgent); 102 + // 创建 Token 令牌,记录登录日志
  103 + return createTokenAfterLoginSuccess(user, null, LoginLogTypeEnum.LOGIN_SOCIAL);
110 } 104 }
111 105
112 @Override 106 @Override
113 - public String socialBindLogin(AppAuthSocialBindLoginReqVO reqVO, String userIp, String userAgent) { 107 + public AppAuthLoginRespVO socialBindLogin(AppAuthSocialBindLoginReqVO reqVO) {
114 // 使用手机号、手机验证码登录 108 // 使用手机号、手机验证码登录
115 AppAuthSmsLoginReqVO loginReqVO = AppAuthSmsLoginReqVO.builder() 109 AppAuthSmsLoginReqVO loginReqVO = AppAuthSmsLoginReqVO.builder()
116 .mobile(reqVO.getMobile()).code(reqVO.getSmsCode()).build(); 110 .mobile(reqVO.getMobile()).code(reqVO.getSmsCode()).build();
117 - String token = this.smsLogin(loginReqVO, userIp, userAgent);  
118 - LoginUser loginUser = userSessionApi.getLoginUser(token); 111 + AppAuthLoginRespVO token = smsLogin(loginReqVO);
119 112
120 // 绑定社交用户 113 // 绑定社交用户
121 - socialUserApi.bindSocialUser(AuthConvert.INSTANCE.convert(loginUser.getId(), getUserType().getValue(), reqVO)); 114 + socialUserApi.bindSocialUser(AuthConvert.INSTANCE.convert(token.getUserId(), getUserType().getValue(), reqVO));
122 return token; 115 return token;
123 } 116 }
124 117
125 - private String createUserSessionAfterLoginSuccess(LoginUser loginUser, String mobile,  
126 - LoginLogTypeEnum logType, String userIp, String userAgent) { 118 + private AppAuthLoginRespVO createTokenAfterLoginSuccess(MemberUserDO user, String mobile, LoginLogTypeEnum logType) {
127 // 插入登陆日志 119 // 插入登陆日志
128 - createLoginLog(loginUser.getId(), mobile, logType, LoginResultEnum.SUCCESS);  
129 - // 缓存登录用户到 Redis 中,返回 Token 令牌  
130 - return userSessionApi.createUserSession(loginUser, userIp, userAgent); 120 + createLoginLog(user.getId(), mobile, logType, LoginResultEnum.SUCCESS);
  121 + // 创建 Token 令牌
  122 + OAuth2AccessTokenRespDTO accessTokenRespDTO = oauth2TokenApi.createAccessToken(new OAuth2AccessTokenCreateReqDTO()
  123 + .setUserId(user.getId()).setUserType(getUserType().getValue()).setClientId(OAuth2ClientIdEnum.DEFAULT.getId()));
  124 + // 构建返回结果
  125 + return AuthConvert.INSTANCE.convert(accessTokenRespDTO);
131 } 126 }
132 127
133 @Override 128 @Override
@@ -135,7 +130,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { @@ -135,7 +130,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
135 return socialUserApi.getAuthorizeUrl(type, redirectUri); 130 return socialUserApi.getAuthorizeUrl(type, redirectUri);
136 } 131 }
137 132
138 - private LoginUser login0(String mobile, String password) { 133 + private MemberUserDO login0(String mobile, String password) {
139 final LoginLogTypeEnum logTypeEnum = LoginLogTypeEnum.LOGIN_MOBILE; 134 final LoginLogTypeEnum logTypeEnum = LoginLogTypeEnum.LOGIN_MOBILE;
140 // 校验账号是否存在 135 // 校验账号是否存在
141 MemberUserDO user = userService.getUserByMobile(mobile); 136 MemberUserDO user = userService.getUserByMobile(mobile);
@@ -152,9 +147,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { @@ -152,9 +147,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
152 createLoginLog(user.getId(), mobile, logTypeEnum, LoginResultEnum.USER_DISABLED); 147 createLoginLog(user.getId(), mobile, logTypeEnum, LoginResultEnum.USER_DISABLED);
153 throw exception(AUTH_LOGIN_USER_DISABLED); 148 throw exception(AUTH_LOGIN_USER_DISABLED);
154 } 149 }
155 -  
156 - // 构建 User 对象  
157 - return buildLoginUser(user); 150 + return user;
158 } 151 }
159 152
160 private void createLoginLog(Long userId, String mobile, LoginLogTypeEnum logType, LoginResultEnum loginResult) { 153 private void createLoginLog(Long userId, String mobile, LoginLogTypeEnum logType, LoginResultEnum loginResult) {
@@ -177,15 +170,13 @@ public class MemberAuthServiceImpl implements MemberAuthService { @@ -177,15 +170,13 @@ public class MemberAuthServiceImpl implements MemberAuthService {
177 170
178 @Override 171 @Override
179 public void logout(String token) { 172 public void logout(String token) {
180 - // 查询用户信息  
181 - LoginUser loginUser = userSessionApi.getLoginUser(token);  
182 - if (loginUser == null) { 173 + // 删除访问令牌
  174 + OAuth2AccessTokenRespDTO accessTokenRespDTO = oauth2TokenApi.removeAccessToken(token);
  175 + if (accessTokenRespDTO == null) {
183 return; 176 return;
184 } 177 }
185 - // 删除 session  
186 - userSessionApi.deleteUserSession(token);  
187 - // 记录登出日志  
188 - createLogoutLog(loginUser.getId()); 178 + // 删除成功,则记录登出日志
  179 + createLogoutLog(accessTokenRespDTO.getUserId());
189 } 180 }
190 181
191 @Override 182 @Override
@@ -219,6 +210,12 @@ public class MemberAuthServiceImpl implements MemberAuthService { @@ -219,6 +210,12 @@ public class MemberAuthServiceImpl implements MemberAuthService {
219 smsCodeApi.sendSmsCode(AuthConvert.INSTANCE.convert(reqVO).setCreateIp(getClientIP())); 210 smsCodeApi.sendSmsCode(AuthConvert.INSTANCE.convert(reqVO).setCreateIp(getClientIP()));
220 } 211 }
221 212
  213 + @Override
  214 + public AppAuthLoginRespVO refreshToken(String refreshToken) {
  215 + OAuth2AccessTokenRespDTO accessTokenDO = oauth2TokenApi.refreshAccessToken(refreshToken, OAuth2ClientIdEnum.DEFAULT.getId());
  216 + return AuthConvert.INSTANCE.convert(accessTokenDO);
  217 + }
  218 +
222 /** 219 /**
223 * 校验旧密码 220 * 校验旧密码
224 * 221 *
@@ -260,10 +257,6 @@ public class MemberAuthServiceImpl implements MemberAuthService { @@ -260,10 +257,6 @@ public class MemberAuthServiceImpl implements MemberAuthService {
260 loginLogApi.createLoginLog(reqDTO); 257 loginLogApi.createLoginLog(reqDTO);
261 } 258 }
262 259
263 - private LoginUser buildLoginUser(MemberUserDO user) {  
264 - return AuthConvert.INSTANCE.convert(user).setUserType(getUserType().getValue());  
265 - }  
266 -  
267 private String getMobile(Long userId) { 260 private String getMobile(Long userId) {
268 if (userId == null) { 261 if (userId == null) {
269 return null; 262 return null;
yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceTest.java
@@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.member.controller.app.auth.vo.AppAuthUpdatePasswo @@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.member.controller.app.auth.vo.AppAuthUpdatePasswo
9 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; 9 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
10 import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper; 10 import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
11 import cn.iocoder.yudao.module.member.service.user.MemberUserService; 11 import cn.iocoder.yudao.module.member.service.user.MemberUserService;
12 -import cn.iocoder.yudao.module.system.api.auth.UserSessionApi; 12 +import cn.iocoder.yudao.module.system.api.auth.OAuth2TokenApi;
13 import cn.iocoder.yudao.module.system.api.logger.LoginLogApi; 13 import cn.iocoder.yudao.module.system.api.logger.LoginLogApi;
14 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; 14 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
15 import cn.iocoder.yudao.module.system.api.social.SocialUserApi; 15 import cn.iocoder.yudao.module.system.api.social.SocialUserApi;
@@ -46,7 +46,7 @@ public class MemberAuthServiceTest extends BaseDbAndRedisUnitTest { @@ -46,7 +46,7 @@ public class MemberAuthServiceTest extends BaseDbAndRedisUnitTest {
46 @MockBean 46 @MockBean
47 private LoginLogApi loginLogApi; 47 private LoginLogApi loginLogApi;
48 @MockBean 48 @MockBean
49 - private UserSessionApi userSessionApi; 49 + private OAuth2TokenApi oauth2TokenApi;
50 @MockBean 50 @MockBean
51 private SocialUserApi socialUserApi; 51 private SocialUserApi socialUserApi;
52 @MockBean 52 @MockBean
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/auth/OAuth2TokenApi.java
@@ -13,10 +13,37 @@ import javax.validation.Valid; @@ -13,10 +13,37 @@ import javax.validation.Valid;
13 */ 13 */
14 public interface OAuth2TokenApi { 14 public interface OAuth2TokenApi {
15 15
  16 + /**
  17 + * 创建访问令牌
  18 + *
  19 + * @param reqDTO 访问令牌的创建信息
  20 + * @return 访问令牌的信息
  21 + */
16 OAuth2AccessTokenRespDTO createAccessToken(@Valid OAuth2AccessTokenCreateReqDTO reqDTO); 22 OAuth2AccessTokenRespDTO createAccessToken(@Valid OAuth2AccessTokenCreateReqDTO reqDTO);
17 23
  24 + /**
  25 + * 校验访问令牌
  26 + *
  27 + * @param accessToken 访问令牌
  28 + * @return 访问令牌的信息
  29 + */
18 OAuth2AccessTokenCheckRespDTO checkAccessToken(String accessToken); 30 OAuth2AccessTokenCheckRespDTO checkAccessToken(String accessToken);
19 31
20 -// void removeToken(OAuth2RemoveTokenByUserReqDTO removeTokenDTO); 32 + /**
  33 + * 移除访问令牌
  34 + *
  35 + * @param accessToken 访问令牌
  36 + * @return 访问令牌的信息
  37 + */
  38 + OAuth2AccessTokenRespDTO removeAccessToken(String accessToken);
  39 +
  40 + /**
  41 + * 刷新访问令牌
  42 + *
  43 + * @param refreshToken 刷新令牌
  44 + * @param clientId 客户端编号
  45 + * @return 访问令牌的信息
  46 + */
  47 + OAuth2AccessTokenRespDTO refreshAccessToken(String refreshToken, Long clientId);
21 48
22 } 49 }
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/auth/dto/OAuth2AccessTokenCreateReqDTO.java
@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.system.api.auth.dto; @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.system.api.auth.dto;
3 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; 3 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
4 import cn.iocoder.yudao.framework.common.validation.InEnum; 4 import cn.iocoder.yudao.framework.common.validation.InEnum;
5 import lombok.Data; 5 import lombok.Data;
6 -import lombok.experimental.Accessors;  
7 6
8 import javax.validation.constraints.NotNull; 7 import javax.validation.constraints.NotNull;
9 import java.io.Serializable; 8 import java.io.Serializable;
@@ -14,14 +13,13 @@ import java.io.Serializable; @@ -14,14 +13,13 @@ import java.io.Serializable;
14 * @author 芋道源码 13 * @author 芋道源码
15 */ 14 */
16 @Data 15 @Data
17 -@Accessors(chain = true)  
18 public class OAuth2AccessTokenCreateReqDTO implements Serializable { 16 public class OAuth2AccessTokenCreateReqDTO implements Serializable {
19 17
20 /** 18 /**
21 * 用户编号 19 * 用户编号
22 */ 20 */
23 @NotNull(message = "用户编号不能为空") 21 @NotNull(message = "用户编号不能为空")
24 - private Integer userId; 22 + private Long userId;
25 /** 23 /**
26 * 用户类型 24 * 用户类型
27 */ 25 */
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/auth/dto/OAuth2AccessTokenRespDTO.java
@@ -26,7 +26,7 @@ public class OAuth2AccessTokenRespDTO implements Serializable { @@ -26,7 +26,7 @@ public class OAuth2AccessTokenRespDTO implements Serializable {
26 /** 26 /**
27 * 用户编号 27 * 用户编号
28 */ 28 */
29 - private Integer userId; 29 + private Long userId;
30 /** 30 /**
31 * 用户类型 31 * 用户类型
32 */ 32 */
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/auth/OAuth2TokenApiImpl.java
@@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenCheckRespDTO @@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenCheckRespDTO
4 import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenCreateReqDTO; 4 import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenCreateReqDTO;
5 import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenRespDTO; 5 import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenRespDTO;
6 import cn.iocoder.yudao.module.system.convert.auth.OAuth2TokenConvert; 6 import cn.iocoder.yudao.module.system.convert.auth.OAuth2TokenConvert;
  7 +import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
7 import cn.iocoder.yudao.module.system.service.auth.OAuth2TokenService; 8 import cn.iocoder.yudao.module.system.service.auth.OAuth2TokenService;
8 import org.springframework.stereotype.Service; 9 import org.springframework.stereotype.Service;
9 10
@@ -22,7 +23,9 @@ public class OAuth2TokenApiImpl implements OAuth2TokenApi { @@ -22,7 +23,9 @@ public class OAuth2TokenApiImpl implements OAuth2TokenApi {
22 23
23 @Override 24 @Override
24 public OAuth2AccessTokenRespDTO createAccessToken(OAuth2AccessTokenCreateReqDTO reqDTO) { 25 public OAuth2AccessTokenRespDTO createAccessToken(OAuth2AccessTokenCreateReqDTO reqDTO) {
25 - return null; 26 + OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.createAccessToken(
  27 + reqDTO.getUserId(), reqDTO.getUserType(), reqDTO.getClientId());
  28 + return OAuth2TokenConvert.INSTANCE.convert2(accessTokenDO);
26 } 29 }
27 30
28 @Override 31 @Override
@@ -30,4 +33,16 @@ public class OAuth2TokenApiImpl implements OAuth2TokenApi { @@ -30,4 +33,16 @@ public class OAuth2TokenApiImpl implements OAuth2TokenApi {
30 return OAuth2TokenConvert.INSTANCE.convert(oauth2TokenService.checkAccessToken(accessToken)); 33 return OAuth2TokenConvert.INSTANCE.convert(oauth2TokenService.checkAccessToken(accessToken));
31 } 34 }
32 35
  36 + @Override
  37 + public OAuth2AccessTokenRespDTO removeAccessToken(String accessToken) {
  38 + OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.removeAccessToken(accessToken);
  39 + return OAuth2TokenConvert.INSTANCE.convert2(accessTokenDO);
  40 + }
  41 +
  42 + @Override
  43 + public OAuth2AccessTokenRespDTO refreshAccessToken(String refreshToken, Long clientId) {
  44 + OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.refreshAccessToken(refreshToken, clientId);
  45 + return OAuth2TokenConvert.INSTANCE.convert2(accessTokenDO);
  46 + }
  47 +
33 } 48 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java
@@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.system.convert.auth.AuthConvert; @@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.system.convert.auth.AuthConvert;
11 import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; 11 import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
12 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; 12 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
13 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; 13 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
  14 +import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
14 import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum; 15 import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum;
15 import cn.iocoder.yudao.module.system.service.auth.AdminAuthService; 16 import cn.iocoder.yudao.module.system.service.auth.AdminAuthService;
16 import cn.iocoder.yudao.module.system.service.permission.PermissionService; 17 import cn.iocoder.yudao.module.system.service.permission.PermissionService;
@@ -70,14 +71,15 @@ public class AuthController { @@ -70,14 +71,15 @@ public class AuthController {
70 public CommonResult<Boolean> logout(HttpServletRequest request) { 71 public CommonResult<Boolean> logout(HttpServletRequest request) {
71 String token = obtainAuthorization(request, securityProperties.getTokenHeader()); 72 String token = obtainAuthorization(request, securityProperties.getTokenHeader());
72 if (StrUtil.isNotBlank(token)) { 73 if (StrUtil.isNotBlank(token)) {
73 - authService.logout(token); 74 + authService.logout(token, LoginLogTypeEnum.LOGOUT_SELF.getType());
74 } 75 }
75 return success(true); 76 return success(true);
76 } 77 }
77 78
78 @PostMapping("/refresh-token") 79 @PostMapping("/refresh-token")
79 @ApiOperation("刷新令牌") 80 @ApiOperation("刷新令牌")
80 - @OperateLog(enable = false) // 避免 Post 请求被记录操作日志 TODO 接口文档 81 + @ApiImplicitParam(name = "refreshToken", value = "刷新令牌", required = true, dataTypeClass = String.class)
  82 + @OperateLog(enable = false) // 避免 Post 请求被记录操作日志
81 public CommonResult<AuthLoginRespVO> refreshToken(@RequestParam("refreshToken") String refreshToken) { 83 public CommonResult<AuthLoginRespVO> refreshToken(@RequestParam("refreshToken") String refreshToken) {
82 return success(authService.refreshToken(refreshToken)); 84 return success(authService.refreshToken(refreshToken));
83 } 85 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/OAuth2TokenController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.controller.admin.auth;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.token.OAuth2AccessTokenPageReqVO;
  6 +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.token.OAuth2AccessTokenRespVO;
  7 +import cn.iocoder.yudao.module.system.convert.auth.OAuth2TokenConvert;
  8 +import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
  9 +import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
  10 +import cn.iocoder.yudao.module.system.service.auth.AdminAuthService;
  11 +import cn.iocoder.yudao.module.system.service.auth.OAuth2TokenService;
  12 +import io.swagger.annotations.Api;
  13 +import io.swagger.annotations.ApiImplicitParam;
  14 +import io.swagger.annotations.ApiOperation;
  15 +import org.springframework.security.access.prepost.PreAuthorize;
  16 +import org.springframework.web.bind.annotation.*;
  17 +
  18 +import javax.annotation.Resource;
  19 +import javax.validation.Valid;
  20 +
  21 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  22 +
  23 +@Api(tags = "管理后台 - OAuth2.0 令牌")
  24 +@RestController
  25 +@RequestMapping("/system/oauth2-token")
  26 +public class OAuth2TokenController {
  27 +
  28 + @Resource
  29 + private OAuth2TokenService oauth2TokenService;
  30 + @Resource
  31 + private AdminAuthService authService;
  32 +
  33 + @GetMapping("/page")
  34 + @ApiOperation(value = "获得访问令牌分页", notes = "只返回有效期内的")
  35 + @PreAuthorize("@ss.hasPermission('system:oauth2-token:page')")
  36 + public CommonResult<PageResult<OAuth2AccessTokenRespVO>> getAccessTokenPage(@Valid OAuth2AccessTokenPageReqVO reqVO) {
  37 + PageResult<OAuth2AccessTokenDO> pageResult = oauth2TokenService.getAccessTokenPage(reqVO);
  38 + return success(OAuth2TokenConvert.INSTANCE.convert(pageResult));
  39 + }
  40 +
  41 + @DeleteMapping("/delete")
  42 + @ApiOperation("删除访问令牌")
  43 + @ApiImplicitParam(name = "accessToken", value = "访问令牌", required = true, dataTypeClass = String.class, example = "tudou")
  44 + @PreAuthorize("@ss.hasPermission('system:oauth2-token:delete')")
  45 + public CommonResult<Boolean> deleteAccessToken(@RequestParam("accessToken") String accessToken) {
  46 + authService.logout(accessToken, LoginLogTypeEnum.LOGOUT_DELETE.getType());
  47 + return success(true);
  48 + }
  49 +
  50 +}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/token/OAuth2AccessTokenPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.controller.admin.auth.vo.token;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.annotations.ApiModel;
  5 +import io.swagger.annotations.ApiModelProperty;
  6 +import lombok.Data;
  7 +import lombok.EqualsAndHashCode;
  8 +
  9 +@ApiModel("管理后台 - 访问令牌分页 Request VO")
  10 +@Data
  11 +@EqualsAndHashCode(callSuper = true)
  12 +public class OAuth2AccessTokenPageReqVO extends PageParam {
  13 +
  14 + @ApiModelProperty(value = "用户编号", required = true, example = "666")
  15 + private Long userId;
  16 +
  17 + @ApiModelProperty(value = "用户类型", required = true, example = "2", notes = "参见 UserTypeEnum 枚举")
  18 + private Integer userType;
  19 +
  20 + @ApiModelProperty(value = "客户端编号", required = true, example = "2")
  21 + private Long clientId;
  22 +
  23 +}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/token/OAuth2AccessTokenRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.controller.admin.auth.vo.token;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.AllArgsConstructor;
  6 +import lombok.Data;
  7 +import lombok.NoArgsConstructor;
  8 +
  9 +import java.util.Date;
  10 +
  11 +@ApiModel("管理后台 - 访问令牌 Response VO")
  12 +@Data
  13 +@NoArgsConstructor
  14 +@AllArgsConstructor
  15 +public class OAuth2AccessTokenRespVO {
  16 +
  17 + @ApiModelProperty(value = "编号", required = true, example = "1024")
  18 + private Long id;
  19 +
  20 + @ApiModelProperty(value = "访问令牌", required = true, example = "tudou")
  21 + private String accessToken;
  22 +
  23 + @ApiModelProperty(value = "刷新令牌", required = true, example = "nice")
  24 + private String refreshToken;
  25 +
  26 + @ApiModelProperty(value = "用户编号", required = true, example = "666")
  27 + private Long userId;
  28 +
  29 + @ApiModelProperty(value = "用户类型", required = true, example = "2", notes = "参见 UserTypeEnum 枚举")
  30 + private Integer userType;
  31 +
  32 + @ApiModelProperty(value = "客户端编号", required = true, example = "2")
  33 + private Long clientId;
  34 +
  35 + @ApiModelProperty(value = "创建时间", required = true)
  36 + private Date createTime;
  37 +
  38 + @ApiModelProperty(value = "过期时间", required = true)
  39 + private Date expiresTime;
  40 +
  41 +}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/auth/OAuth2TokenConvert.java
1 package cn.iocoder.yudao.module.system.convert.auth; 1 package cn.iocoder.yudao.module.system.convert.auth;
2 2
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
3 import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenCheckRespDTO; 4 import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenCheckRespDTO;
  5 +import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenRespDTO;
  6 +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.token.OAuth2AccessTokenRespVO;
4 import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO; 7 import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
5 import org.mapstruct.Mapper; 8 import org.mapstruct.Mapper;
6 import org.mapstruct.factory.Mappers; 9 import org.mapstruct.factory.Mappers;
@@ -12,4 +15,8 @@ public interface OAuth2TokenConvert { @@ -12,4 +15,8 @@ public interface OAuth2TokenConvert {
12 15
13 OAuth2AccessTokenCheckRespDTO convert(OAuth2AccessTokenDO bean); 16 OAuth2AccessTokenCheckRespDTO convert(OAuth2AccessTokenDO bean);
14 17
  18 + PageResult<OAuth2AccessTokenRespVO> convert(PageResult<OAuth2AccessTokenDO> page);
  19 +
  20 + OAuth2AccessTokenRespDTO convert2(OAuth2AccessTokenDO bean);
  21 +
15 } 22 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/auth/OAuth2AccessTokenMapper.java
1 package cn.iocoder.yudao.module.system.dal.mysql.auth; 1 package cn.iocoder.yudao.module.system.dal.mysql.auth;
2 2
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.token.OAuth2AccessTokenPageReqVO;
4 import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO; 7 import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
5 import org.apache.ibatis.annotations.Mapper; 8 import org.apache.ibatis.annotations.Mapper;
6 9
  10 +import java.util.Date;
7 import java.util.List; 11 import java.util.List;
8 12
9 @Mapper 13 @Mapper
@@ -17,4 +21,13 @@ public interface OAuth2AccessTokenMapper extends BaseMapperX&lt;OAuth2AccessTokenDO @@ -17,4 +21,13 @@ public interface OAuth2AccessTokenMapper extends BaseMapperX&lt;OAuth2AccessTokenDO
17 return selectList(OAuth2AccessTokenDO::getRefreshToken, refreshToken); 21 return selectList(OAuth2AccessTokenDO::getRefreshToken, refreshToken);
18 } 22 }
19 23
  24 + default PageResult<OAuth2AccessTokenDO> selectPage(OAuth2AccessTokenPageReqVO reqVO) {
  25 + return selectPage(reqVO, new LambdaQueryWrapperX<OAuth2AccessTokenDO>()
  26 + .eqIfPresent(OAuth2AccessTokenDO::getUserId, reqVO.getUserId())
  27 + .eqIfPresent(OAuth2AccessTokenDO::getUserType, reqVO.getUserType())
  28 + .eqIfPresent(OAuth2AccessTokenDO::getClientId, reqVO.getClientId())
  29 + .gt(OAuth2AccessTokenDO::getExpiresTime, new Date())
  30 + .orderByDesc(OAuth2AccessTokenDO::getId));
  31 + }
  32 +
20 } 33 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthService.java
@@ -25,8 +25,9 @@ public interface AdminAuthService { @@ -25,8 +25,9 @@ public interface AdminAuthService {
25 * 基于 token 退出登录 25 * 基于 token 退出登录
26 * 26 *
27 * @param token token 27 * @param token token
  28 + * @param logType 登出类型
28 */ 29 */
29 - void logout(String token); 30 + void logout(String token, Integer logType);
30 31
31 /** 32 /**
32 * 短信验证码发送 33 * 短信验证码发送
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java
@@ -18,6 +18,7 @@ import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum; @@ -18,6 +18,7 @@ import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
18 import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; 18 import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
19 import cn.iocoder.yudao.module.system.service.common.CaptchaService; 19 import cn.iocoder.yudao.module.system.service.common.CaptchaService;
20 import cn.iocoder.yudao.module.system.service.logger.LoginLogService; 20 import cn.iocoder.yudao.module.system.service.logger.LoginLogService;
  21 +import cn.iocoder.yudao.module.system.service.member.MemberService;
21 import cn.iocoder.yudao.module.system.service.social.SocialUserService; 22 import cn.iocoder.yudao.module.system.service.social.SocialUserService;
22 import cn.iocoder.yudao.module.system.service.user.AdminUserService; 23 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
23 import com.google.common.annotations.VisibleForTesting; 24 import com.google.common.annotations.VisibleForTesting;
@@ -51,6 +52,8 @@ public class AdminAuthServiceImpl implements AdminAuthService { @@ -51,6 +52,8 @@ public class AdminAuthServiceImpl implements AdminAuthService {
51 private OAuth2TokenService oauth2TokenService; 52 private OAuth2TokenService oauth2TokenService;
52 @Resource 53 @Resource
53 private SocialUserService socialUserService; 54 private SocialUserService socialUserService;
  55 + @Resource
  56 + private MemberService memberService;
54 57
55 @Resource 58 @Resource
56 private Validator validator; 59 private Validator validator;
@@ -209,23 +212,27 @@ public class AdminAuthServiceImpl implements AdminAuthService { @@ -209,23 +212,27 @@ public class AdminAuthServiceImpl implements AdminAuthService {
209 } 212 }
210 213
211 @Override 214 @Override
212 - public void logout(String token) { 215 + public void logout(String token, Integer logType) {
213 // 删除访问令牌 216 // 删除访问令牌
214 OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.removeAccessToken(token); 217 OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.removeAccessToken(token);
215 if (accessTokenDO == null) { 218 if (accessTokenDO == null) {
216 return; 219 return;
217 } 220 }
218 // 删除成功,则记录登出日志 221 // 删除成功,则记录登出日志
219 - createLogoutLog(accessTokenDO.getUserId()); 222 + createLogoutLog(accessTokenDO.getUserId(), accessTokenDO.getUserType(), logType);
220 } 223 }
221 224
222 - private void createLogoutLog(Long userId) { 225 + private void createLogoutLog(Long userId, Integer userType, Integer logType) {
223 LoginLogCreateReqDTO reqDTO = new LoginLogCreateReqDTO(); 226 LoginLogCreateReqDTO reqDTO = new LoginLogCreateReqDTO();
224 - reqDTO.setLogType(LoginLogTypeEnum.LOGOUT_SELF.getType()); 227 + reqDTO.setLogType(logType);
225 reqDTO.setTraceId(TracerUtils.getTraceId()); 228 reqDTO.setTraceId(TracerUtils.getTraceId());
226 reqDTO.setUserId(userId); 229 reqDTO.setUserId(userId);
227 - reqDTO.setUsername(getUsername(userId));  
228 - reqDTO.setUserType(getUserType().getValue()); 230 + reqDTO.setUserType(userType);
  231 + if (ObjectUtil.notEqual(getUserType(), userType)) {
  232 + reqDTO.setUsername(getUsername(userId));
  233 + } else {
  234 + reqDTO.setUsername(memberService.getMemberUserMobile(userId));
  235 + }
229 reqDTO.setUserAgent(ServletUtils.getUserAgent()); 236 reqDTO.setUserAgent(ServletUtils.getUserAgent());
230 reqDTO.setUserIp(ServletUtils.getClientIP()); 237 reqDTO.setUserIp(ServletUtils.getClientIP());
231 reqDTO.setResult(LoginResultEnum.SUCCESS.getResult()); 238 reqDTO.setResult(LoginResultEnum.SUCCESS.getResult());
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/OAuth2TokenService.java
1 package cn.iocoder.yudao.module.system.service.auth; 1 package cn.iocoder.yudao.module.system.service.auth;
2 2
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.token.OAuth2AccessTokenPageReqVO;
3 import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO; 5 import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
4 6
5 /** 7 /**
@@ -64,4 +66,12 @@ public interface OAuth2TokenService { @@ -64,4 +66,12 @@ public interface OAuth2TokenService {
64 */ 66 */
65 OAuth2AccessTokenDO removeAccessToken(String accessToken); 67 OAuth2AccessTokenDO removeAccessToken(String accessToken);
66 68
  69 + /**
  70 + * 获得访问令牌分页
  71 + *
  72 + * @param reqVO 请求
  73 + * @return 访问令牌分页
  74 + */
  75 + PageResult<OAuth2AccessTokenDO> getAccessTokenPage(OAuth2AccessTokenPageReqVO reqVO);
  76 +
67 } 77 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/OAuth2TokenServiceImpl.java
@@ -4,8 +4,10 @@ import cn.hutool.core.collection.CollUtil; @@ -4,8 +4,10 @@ import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.util.IdUtil; 4 import cn.hutool.core.util.IdUtil;
5 import cn.hutool.core.util.ObjectUtil; 5 import cn.hutool.core.util.ObjectUtil;
6 import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; 6 import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
  7 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
7 import cn.iocoder.yudao.framework.common.util.date.DateUtils; 8 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
8 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; 9 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
  10 +import cn.iocoder.yudao.module.system.controller.admin.auth.vo.token.OAuth2AccessTokenPageReqVO;
9 import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO; 11 import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
10 import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2ClientDO; 12 import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2ClientDO;
11 import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2RefreshTokenDO; 13 import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2RefreshTokenDO;
@@ -125,6 +127,11 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService { @@ -125,6 +127,11 @@ public class OAuth2TokenServiceImpl implements OAuth2TokenService {
125 return accessTokenDO; 127 return accessTokenDO;
126 } 128 }
127 129
  130 + @Override
  131 + public PageResult<OAuth2AccessTokenDO> getAccessTokenPage(OAuth2AccessTokenPageReqVO reqVO) {
  132 + return oauth2AccessTokenMapper.selectPage(reqVO);
  133 + }
  134 +
128 private OAuth2AccessTokenDO createOAuth2AccessToken(OAuth2RefreshTokenDO refreshTokenDO, OAuth2ClientDO clientDO) { 135 private OAuth2AccessTokenDO createOAuth2AccessToken(OAuth2RefreshTokenDO refreshTokenDO, OAuth2ClientDO clientDO) {
129 OAuth2AccessTokenDO accessTokenDO = new OAuth2AccessTokenDO().setAccessToken(generateAccessToken()) 136 OAuth2AccessTokenDO accessTokenDO = new OAuth2AccessTokenDO().setAccessToken(generateAccessToken())
130 .setUserId(refreshTokenDO.getUserId()).setUserType(refreshTokenDO.getUserType()).setClientId(clientDO.getId()) 137 .setUserId(refreshTokenDO.getUserId()).setUserType(refreshTokenDO.getUserType()).setClientId(clientDO.getId())
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AuthServiceImplTest.java
@@ -221,7 +221,7 @@ public class AuthServiceImplTest extends BaseDbUnitTest { @@ -221,7 +221,7 @@ public class AuthServiceImplTest extends BaseDbUnitTest {
221 when(oauth2TokenService.removeAccessToken(eq(token))).thenReturn(accessTokenDO); 221 when(oauth2TokenService.removeAccessToken(eq(token))).thenReturn(accessTokenDO);
222 222
223 // 调用 223 // 调用
224 - authService.logout(token); 224 + authService.logout(token, LoginLogTypeEnum.LOGOUT_SELF.getType());
225 // 校验调用参数 225 // 校验调用参数
226 verify(loginLogService).createLoginLog(argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGOUT_SELF.getType()) 226 verify(loginLogService).createLoginLog(argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGOUT_SELF.getType())
227 && o.getResult().equals(LoginResultEnum.SUCCESS.getResult())) 227 && o.getResult().equals(LoginResultEnum.SUCCESS.getResult()))
@@ -234,7 +234,7 @@ public class AuthServiceImplTest extends BaseDbUnitTest { @@ -234,7 +234,7 @@ public class AuthServiceImplTest extends BaseDbUnitTest {
234 String token = randomString(); 234 String token = randomString();
235 235
236 // 调用 236 // 调用
237 - authService.logout(token); 237 + authService.logout(token, LoginLogTypeEnum.LOGOUT_SELF.getType());
238 // 校验调用参数 238 // 校验调用参数
239 verify(loginLogService, never()).createLoginLog(any()); 239 verify(loginLogService, never()).createLoginLog(any());
240 } 240 }
yudao-server/pom.xml
@@ -21,11 +21,11 @@ @@ -21,11 +21,11 @@
21 <url>https://github.com/YunaiV/ruoyi-vue-pro</url> 21 <url>https://github.com/YunaiV/ruoyi-vue-pro</url>
22 22
23 <dependencies> 23 <dependencies>
24 -<!-- <dependency>-->  
25 -<!-- <groupId>cn.iocoder.boot</groupId>-->  
26 -<!-- <artifactId>yudao-module-member-biz</artifactId>-->  
27 -<!-- <version>${revision}</version>-->  
28 -<!-- </dependency>--> 24 + <dependency>
  25 + <groupId>cn.iocoder.boot</groupId>
  26 + <artifactId>yudao-module-member-biz</artifactId>
  27 + <version>${revision}</version>
  28 + </dependency>
29 <dependency> 29 <dependency>
30 <groupId>cn.iocoder.boot</groupId> 30 <groupId>cn.iocoder.boot</groupId>
31 <artifactId>yudao-module-system-biz</artifactId> 31 <artifactId>yudao-module-system-biz</artifactId>
yudao-server/src/main/resources/application-dev.yaml
@@ -173,8 +173,6 @@ wx: # 参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-sta @@ -173,8 +173,6 @@ wx: # 参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-sta
173 yudao: 173 yudao:
174 security: 174 security:
175 token-header: Authorization 175 token-header: Authorization
176 - token-timeout: 1d  
177 - session-timeout: 30m  
178 mock-enable: true 176 mock-enable: true
179 mock-secret: test 177 mock-secret: test
180 xss: 178 xss:
yudao-server/src/main/resources/application-local.yaml
@@ -193,8 +193,6 @@ yudao: @@ -193,8 +193,6 @@ yudao:
193 enable: false # 本地环境,暂时关闭图片验证码,方便登录等接口的测试 193 enable: false # 本地环境,暂时关闭图片验证码,方便登录等接口的测试
194 security: 194 security:
195 token-header: Authorization 195 token-header: Authorization
196 - token-timeout: 1d  
197 - session-timeout: 1d  
198 mock-enable: true 196 mock-enable: true
199 mock-secret: test 197 mock-secret: test
200 xss: 198 xss:
yudao-ui-admin/src/api/system/session.js renamed to yudao-ui-admin/src/api/system/oauth2/oauth2Token.js
1 import request from '@/utils/request' 1 import request from '@/utils/request'
2 2
3 -// 查询在线用户列表  
4 -export function list(query) { 3 +// 获得访问令牌分页
  4 +export function getAccessTokenPage(query) {
5 return request({ 5 return request({
6 - url: '/system/user-session/page', 6 + url: '/system/oauth2-token/page',
7 method: 'get', 7 method: 'get',
8 params: query 8 params: query
9 }) 9 })
10 } 10 }
11 11
12 -// 强退用户  
13 -export function forceLogout(tokenId) { 12 +// 删除访问令牌
  13 +export function deleteAccessToken(accessToken) {
14 return request({ 14 return request({
15 - url: '/system/user-session/delete?id=' + tokenId, 15 + url: '/system/oauth2-token/delete?accessToken=' + accessToken,
16 method: 'delete' 16 method: 'delete'
17 }) 17 })
18 } 18 }
yudao-ui-admin/src/views/system/session/index.vue renamed to yudao-ui-admin/src/views/system/oauth2/token/index.vue
@@ -3,11 +3,14 @@ @@ -3,11 +3,14 @@
3 <doc-alert title="用户体系" url="https://doc.iocoder.cn/user-center/" /> 3 <doc-alert title="用户体系" url="https://doc.iocoder.cn/user-center/" />
4 <!-- 搜索工作栏 --> 4 <!-- 搜索工作栏 -->
5 <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="68px"> 5 <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="68px">
6 - <el-form-item label="登录地址" prop="userIp">  
7 - <el-input v-model="queryParams.userIp" placeholder="请输入登录地址" clearable @keyup.enter.native="handleQuery"/> 6 + <el-form-item label="用户编号" prop="userId">
  7 + <el-input v-model="queryParams.userId" placeholder="请输入用户编号" clearable @keyup.enter.native="handleQuery"/>
8 </el-form-item> 8 </el-form-item>
9 - <el-form-item label="用户名称" prop="username">  
10 - <el-input v-model="queryParams.username" placeholder="请输入用户名称" clearable @keyup.enter.native="handleQuery"/> 9 + <el-form-item label="用户类型" prop="userType">
  10 + <el-select v-model="queryParams.userType" placeholder="请选择用户类型" clearable>
  11 + <el-option v-for="dict in this.getDictDatas(DICT_TYPE.USER_TYPE)"
  12 + :key="dict.value" :label="dict.label" :value="dict.value"/>
  13 + </el-select>
11 </el-form-item> 14 </el-form-item>
12 <el-form-item> 15 <el-form-item>
13 <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button> 16 <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
@@ -16,20 +19,28 @@ @@ -16,20 +19,28 @@
16 19
17 </el-form> 20 </el-form>
18 <el-table v-loading="loading" :data="list" style="width: 100%;"> 21 <el-table v-loading="loading" :data="list" style="width: 100%;">
19 - <el-table-column label="会话编号" align="center" prop="id" width="300" />  
20 - <el-table-column label="登录名称" align="center" prop="username" width="100" />  
21 - <el-table-column label="部门名称" align="center" prop="deptName" width="100" />  
22 - <el-table-column label="登录地址" align="center" prop="userIp" width="100" />  
23 - <el-table-column label="userAgent" align="center" prop="userAgent" :show-overflow-tooltip="true" />  
24 - <el-table-column label="登录时间" align="center" prop="createTime" width="180"> 22 + <el-table-column label="访问令牌" align="center" prop="accessToken" width="300" />
  23 + <el-table-column label="刷新令牌" align="center" prop="refreshToken" width="300" />
  24 + <el-table-column label="用户编号" align="center" prop="userId" />
  25 + <el-table-column label="用户类型" align="center" prop="userType" width="100">
  26 + <template slot-scope="scope">
  27 + <dict-tag :type="DICT_TYPE.USER_TYPE" :value="scope.row.userType"/>
  28 + </template>
  29 + </el-table-column>
  30 + <el-table-column label="创建时间" align="center" prop="createTime" width="180">
25 <template slot-scope="scope"> 31 <template slot-scope="scope">
26 <span>{{ parseTime(scope.row.createTime) }}</span> 32 <span>{{ parseTime(scope.row.createTime) }}</span>
27 </template> 33 </template>
28 </el-table-column> 34 </el-table-column>
  35 + <el-table-column label="过期时间" align="center" prop="expiresTime" width="180">
  36 + <template slot-scope="scope">
  37 + <span>{{ parseTime(scope.row.expiresTime) }}</span>
  38 + </template>
  39 + </el-table-column>
29 <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> 40 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
30 <template slot-scope="scope"> 41 <template slot-scope="scope">
31 <el-button size="mini" type="text" icon="el-icon-delete" @click="handleForceLogout(scope.row)" 42 <el-button size="mini" type="text" icon="el-icon-delete" @click="handleForceLogout(scope.row)"
32 - v-hasPermi="['system:user-session:delete']">强退</el-button> 43 + v-hasPermi="['system:oauth2-token:delete']">强退</el-button>
33 </template> 44 </template>
34 </el-table-column> 45 </el-table-column>
35 </el-table> 46 </el-table>
@@ -40,10 +51,10 @@ @@ -40,10 +51,10 @@
40 </template> 51 </template>
41 52
42 <script> 53 <script>
43 -import { list, forceLogout } from "@/api/system/session"; 54 +import { getAccessTokenPage, deleteAccessToken } from "@/api/system/oauth2/oauth2Token";
44 55
45 export default { 56 export default {
46 - name: "Online", 57 + name: "OAuth2Token",
47 data() { 58 data() {
48 return { 59 return {
49 // 遮罩层 60 // 遮罩层
@@ -56,8 +67,8 @@ export default { @@ -56,8 +67,8 @@ export default {
56 queryParams: { 67 queryParams: {
57 pageNo: 1, 68 pageNo: 1,
58 pageSize: 10, 69 pageSize: 10,
59 - userIp: undefined,  
60 - username: undefined 70 + userId: undefined,
  71 + userType: undefined
61 } 72 }
62 }; 73 };
63 }, 74 },
@@ -68,7 +79,7 @@ export default { @@ -68,7 +79,7 @@ export default {
68 /** 查询登录日志列表 */ 79 /** 查询登录日志列表 */
69 getList() { 80 getList() {
70 this.loading = true; 81 this.loading = true;
71 - list(this.queryParams).then(response => { 82 + getAccessTokenPage(this.queryParams).then(response => {
72 this.list = response.data.list; 83 this.list = response.data.list;
73 this.total = response.data.total; 84 this.total = response.data.total;
74 this.loading = false; 85 this.loading = false;
@@ -86,8 +97,8 @@ export default { @@ -86,8 +97,8 @@ export default {
86 }, 97 },
87 /** 强退按钮操作 */ 98 /** 强退按钮操作 */
88 handleForceLogout(row) { 99 handleForceLogout(row) {
89 - this.$modal.confirm('是否确认强退名称为"' + row.username + '"的数据项?').then(function() {  
90 - return forceLogout(row.id); 100 + this.$modal.confirm('是否确认强退令牌为"' + row.accessToken + '"的数据项?').then(function() {
  101 + return deleteAccessToken(row.accessToken);
91 }).then(() => { 102 }).then(() => {
92 this.getList(); 103 this.getList();
93 this.$modal.msgSuccess("强退成功"); 104 this.$modal.msgSuccess("强退成功");