Browse Source

登录后,返回 OAuth2 的 access token + refresh token

YunaiV 2 years ago
parent
commit
86e6c04e07
29 changed files with 134 additions and 680 deletions
  1. 17 0
      yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/auth/OAuth2ClientIdEnum.java
  2. 2 2
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/auth/OAuth2TokenApiImpl.java
  3. 4 9
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java
  4. 0 81
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/UserSessionController.java
  5. 14 3
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/auth/AuthLoginRespVO.java
  6. 0 38
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/session/UserSessionPageItemRespVO.java
  7. 0 20
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/session/UserSessionPageReqVO.java
  8. 2 2
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/auth/AuthConvert.java
  9. 2 6
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/auth/UserSessionConvert.java
  10. 0 72
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/auth/UserSessionDO.java
  11. 0 37
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/auth/UserSessionMapper.java
  12. 0 5
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/redis/RedisKeyConstants.java
  13. 0 52
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/redis/auth/LoginUserRedisDAO.java
  14. 8 10
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthService.java
  15. 10 8
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java
  16. 0 36
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/UserSessionService.java
  17. 0 98
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/UserSessionServiceImpl.java
  18. 28 19
      yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AuthServiceImplTest.java
  19. 0 139
      yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/UserSessionServiceImplTest.java
  20. 2 2
      yudao-ui-admin/src/components/Editor/index.vue
  21. 2 2
      yudao-ui-admin/src/components/FileUpload/index.vue
  22. 2 2
      yudao-ui-admin/src/components/ImageUpload/index.vue
  23. 3 3
      yudao-ui-admin/src/components/UploadImage/index.vue
  24. 2 2
      yudao-ui-admin/src/permission.js
  25. 17 20
      yudao-ui-admin/src/store/modules/user.js
  26. 12 5
      yudao-ui-admin/src/utils/auth.js
  27. 4 4
      yudao-ui-admin/src/utils/request.js
  28. 2 2
      yudao-ui-admin/src/views/infra/file/index.vue
  29. 1 1
      yudao-ui-admin/src/views/system/user/index.vue

+ 17 - 0
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/auth/OAuth2ClientIdEnum.java

@@ -0,0 +1,17 @@
+package cn.iocoder.yudao.module.system.enums.auth;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * OAuth2.0 客户端的编号枚举
+ */
+@AllArgsConstructor
+@Getter
+public enum OAuth2ClientIdEnum {
+
+    DEFAULT(1L); // 系统默认
+
+    private final Long id;
+
+}

+ 2 - 2
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/auth/OAuth2TokenApiImpl.java

@@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.system.api.auth;
 import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenCheckRespDTO;
 import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenCreateReqDTO;
 import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenRespDTO;
-import cn.iocoder.yudao.module.system.convert.auth.UserSessionConvert;
+import cn.iocoder.yudao.module.system.convert.auth.OAuth2TokenConvert;
 import cn.iocoder.yudao.module.system.service.auth.OAuth2TokenService;
 import org.springframework.stereotype.Service;
 
@@ -27,7 +27,7 @@ public class OAuth2TokenApiImpl implements OAuth2TokenApi {
 
     @Override
     public OAuth2AccessTokenCheckRespDTO checkAccessToken(String accessToken) {
-        return UserSessionConvert.INSTANCE.convert(oauth2TokenService.checkAccessToken(accessToken));
+        return OAuth2TokenConvert.INSTANCE.convert(oauth2TokenService.checkAccessToken(accessToken));
     }
 
 }

+ 4 - 9
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java

@@ -61,8 +61,7 @@ public class AuthController {
     @ApiOperation("使用账号密码登录")
     @OperateLog(enable = false) // 避免 Post 请求被记录操作日志
     public CommonResult<AuthLoginRespVO> login(@RequestBody @Valid AuthLoginReqVO reqVO) {
-        String token = authService.login(reqVO);
-        return success(AuthLoginRespVO.builder().token(token).build());
+        return success(authService.login(reqVO));
     }
 
     @PostMapping("/logout")
@@ -114,9 +113,7 @@ public class AuthController {
     @ApiOperation("使用短信验证码登录")
     @OperateLog(enable = false) // 避免 Post 请求被记录操作日志
     public CommonResult<AuthLoginRespVO> smsLogin(@RequestBody @Valid AuthSmsLoginReqVO reqVO) {
-        String token = authService.smsLogin(reqVO);
-        // 返回结果
-        return success(AuthLoginRespVO.builder().token(token).build());
+        return success(authService.smsLogin(reqVO));
     }
 
     @PostMapping("/send-sms-code")
@@ -144,16 +141,14 @@ public class AuthController {
     @ApiOperation("社交快捷登录,使用 code 授权码")
     @OperateLog(enable = false) // 避免 Post 请求被记录操作日志
     public CommonResult<AuthLoginRespVO> socialQuickLogin(@RequestBody @Valid AuthSocialQuickLoginReqVO reqVO) {
-        String token = authService.socialQuickLogin(reqVO);
-        return success(AuthLoginRespVO.builder().token(token).build());
+        return success(authService.socialQuickLogin(reqVO));
     }
 
     @PostMapping("/social-bind-login")
     @ApiOperation("社交绑定登录,使用 code 授权码 + 账号密码")
     @OperateLog(enable = false) // 避免 Post 请求被记录操作日志
     public CommonResult<AuthLoginRespVO> socialBindLogin(@RequestBody @Valid AuthSocialBindLoginReqVO reqVO) {
-        String token = authService.socialBindLogin(reqVO);
-        return success(AuthLoginRespVO.builder().token(token).build());
+        return success(authService.socialBindLogin(reqVO));
     }
 
 }

+ 0 - 81
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/UserSessionController.java

@@ -1,81 +0,0 @@
-package cn.iocoder.yudao.module.system.controller.admin.auth;
-
-import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
-import cn.iocoder.yudao.module.system.controller.admin.auth.vo.session.UserSessionPageItemRespVO;
-import cn.iocoder.yudao.module.system.controller.admin.auth.vo.session.UserSessionPageReqVO;
-import cn.iocoder.yudao.module.system.convert.auth.UserSessionConvert;
-import cn.iocoder.yudao.module.system.dal.dataobject.auth.UserSessionDO;
-import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
-import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
-import cn.iocoder.yudao.module.system.service.auth.UserSessionService;
-import cn.iocoder.yudao.module.system.service.dept.DeptService;
-import cn.iocoder.yudao.module.system.service.user.AdminUserService;
-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 java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
-
-@Api(tags = "管理后台 - 用户 Session")
-@RestController
-@RequestMapping("/system/user-session")
-public class UserSessionController {
-
-    @Resource
-    private UserSessionService userSessionService;
-    @Resource
-    private AdminUserService userService;
-
-    @Resource
-    private DeptService deptService;
-
-    @GetMapping("/page")
-    @ApiOperation("获得 Session 分页列表")
-    @PreAuthorize("@ss.hasPermission('system:user-session:page')")
-    public CommonResult<PageResult<UserSessionPageItemRespVO>> getUserSessionPage(@Validated UserSessionPageReqVO reqVO) {
-        // 获得 Session 分页
-        PageResult<UserSessionDO> pageResult = userSessionService.getUserSessionPage(reqVO);
-
-        // 获得拼接需要的数据
-        Map<Long, AdminUserDO> userMap = userService.getUserMap(
-                convertList(pageResult.getList(), UserSessionDO::getUserId,
-                        session -> session.getUserType().equals(UserTypeEnum.ADMIN.getValue())));
-        Map<Long, DeptDO> deptMap = deptService.getDeptMap(
-                convertList(userMap.values(), AdminUserDO::getDeptId));
-        // 拼接结果返回
-        List<UserSessionPageItemRespVO> sessionList = new ArrayList<>(pageResult.getList().size());
-        pageResult.getList().forEach(session -> {
-            UserSessionPageItemRespVO respVO = UserSessionConvert.INSTANCE.convert(session);
-            sessionList.add(respVO);
-            // 设置用户账号
-            MapUtils.findAndThen(userMap, session.getUserId(), user -> {
-                respVO.setUsername(user.getUsername());
-                // 设置用户部门
-                MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> respVO.setDeptName(dept.getName()));
-            });
-        });
-        return success(new PageResult<>(sessionList, pageResult.getTotal()));
-    }
-
-    @DeleteMapping("/delete")
-    @ApiOperation("删除 Session")
-    @ApiImplicitParam(name = "id", value = "Session 编号", required = true, dataTypeClass = Long.class, example = "1024")
-    @PreAuthorize("@ss.hasPermission('system:user-session:delete')")
-    public CommonResult<Boolean> deleteUserSession(@RequestParam("id") Long id) {
-        userSessionService.deleteUserSession(id);
-        return success(true);
-    }
-
-}

+ 14 - 3
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/auth/AuthLoginRespVO.java

@@ -7,14 +7,25 @@ import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
-@ApiModel("管理后台 - 账号密码登录 Response VO")
+import java.util.Date;
+
+@ApiModel("管理后台 - 登录 Response VO")
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
 @Builder
 public class AuthLoginRespVO {
 
-    @ApiModelProperty(value = "token", required = true, example = "yudaoyuanma")
-    private String token;
+    @ApiModelProperty(value = "用户编号", required = true, example = "1024")
+    private Long userId;
+
+    @ApiModelProperty(value = "访问令牌", required = true, example = "happy")
+    private String accessToken;
+
+    @ApiModelProperty(value = "刷新令牌", required = true, example = "nice")
+    private String refreshToken;
+
+    @ApiModelProperty(value = "过期时间", required = true)
+    private Date expiresTime;
 
 }

+ 0 - 38
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/session/UserSessionPageItemRespVO.java

@@ -1,38 +0,0 @@
-package cn.iocoder.yudao.module.system.controller.admin.auth.vo.session;
-
-import cn.iocoder.yudao.framework.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;
-
-import java.util.Date;
-
-@ApiModel(value = "管理后台 - 用户在线 Session Response VO", description = "相比用户基本信息来说,会多部门、用户账号等信息")
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-@EqualsAndHashCode(callSuper = true)
-public class UserSessionPageItemRespVO 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 Date createTime;
-
-    @ApiModelProperty(value = "用户账号", required = true, example = "yudao")
-    private String username;
-
-    @ApiModelProperty(value = "部门名称", example = "研发部")
-    private String deptName;
-
-}

+ 0 - 20
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/session/UserSessionPageReqVO.java

@@ -1,20 +0,0 @@
-package cn.iocoder.yudao.module.system.controller.admin.auth.vo.session;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-@ApiModel("管理后台 - 在线用户 Session 分页 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-public class UserSessionPageReqVO extends PageParam {
-
-    @ApiModelProperty(value = "用户 IP", example = "127.0.0.1", notes = "模糊匹配")
-    private String userIp;
-
-    @ApiModelProperty(value = "用户账号", example = "yudao", notes = "模糊匹配")
-    private String username;
-
-}

+ 2 - 2
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/auth/AuthConvert.java

@@ -1,11 +1,11 @@
 package cn.iocoder.yudao.module.system.convert.auth;
 
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
-import cn.iocoder.yudao.framework.security.core.LoginUser;
 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeSendReqDTO;
 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
 import cn.iocoder.yudao.module.system.controller.admin.auth.vo.auth.*;
+import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
@@ -21,7 +21,7 @@ public interface AuthConvert {
 
     AuthConvert INSTANCE = Mappers.getMapper(AuthConvert.class);
 
-    LoginUser convert(AdminUserDO bean);
+    AuthLoginRespVO convert(OAuth2AccessTokenDO bean);
 
     default AuthPermissionInfoRespVO convert(AdminUserDO user, List<RoleDO> roleList, List<MenuDO> menuList) {
         return AuthPermissionInfoRespVO.builder()

+ 2 - 6
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/auth/UserSessionConvert.java

@@ -1,18 +1,14 @@
 package cn.iocoder.yudao.module.system.convert.auth;
 
 import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenCheckRespDTO;
-import cn.iocoder.yudao.module.system.controller.admin.auth.vo.session.UserSessionPageItemRespVO;
 import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
-import cn.iocoder.yudao.module.system.dal.dataobject.auth.UserSessionDO;
 import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
 
 @Mapper
-public interface UserSessionConvert {
+public interface OAuth2TokenConvert {
 
-    UserSessionConvert INSTANCE = Mappers.getMapper(UserSessionConvert.class);
-
-    UserSessionPageItemRespVO convert(UserSessionDO session);
+    OAuth2TokenConvert INSTANCE = Mappers.getMapper(OAuth2TokenConvert.class);
 
     OAuth2AccessTokenCheckRespDTO convert(OAuth2AccessTokenDO bean);
 

+ 0 - 72
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/auth/UserSessionDO.java

@@ -1,72 +0,0 @@
-package cn.iocoder.yudao.module.system.dal.dataobject.auth;
-
-import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-import cn.iocoder.yudao.framework.security.core.LoginUser;
-import com.baomidou.mybatisplus.annotation.*;
-import lombok.Builder;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-import java.util.Date;
-
-/**
- * 在线用户表
- *
- * 我们已经将 {@link LoginUser} 缓存在 Redis 当中。
- * 这里额外存储在线用户到 MySQL 中,目的是为了方便管理界面可以灵活查询。
- * 同时,通过定时轮询 UserSessionDO 表,可以主动删除 Redis 的缓存,因为 Redis 的过期删除是延迟的。
- *
- * @author 芋道源码
- */
-@TableName(value = "system_user_session")
-@KeySequence(value = "system_user_session_seq")
-@Data
-@Builder
-@EqualsAndHashCode(callSuper = true)
-@Deprecated
-public class UserSessionDO extends BaseDO {
-
-    /**
-     * 会话编号
-     */
-    private Long id;
-    /**
-     * 令牌
-     */
-    private String token;
-
-    /**
-     * 用户编号
-     *
-     * 关联 AdminUserDO.id 或者 MemberUserDO.id
-     */
-    private Long userId;
-    /**
-     * 用户类型
-     *
-     * 枚举 {@link UserTypeEnum}
-     */
-    private Integer userType;
-
-    /**
-     * 用户账号
-     *
-     * 冗余,因为账号可以变更
-     */
-    private String username;
-
-    /**
-     * 用户 IP
-     */
-    private String userIp;
-    /**
-     * 浏览器 UA
-     */
-    private String userAgent;
-    /**
-     * 会话超时时间
-     */
-    private Date sessionTimeout;
-
-}

+ 0 - 37
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/auth/UserSessionMapper.java

@@ -1,37 +0,0 @@
-package cn.iocoder.yudao.module.system.dal.mysql.auth;
-
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
-import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
-import cn.iocoder.yudao.module.system.controller.admin.auth.vo.session.UserSessionPageReqVO;
-import cn.iocoder.yudao.module.system.dal.dataobject.auth.UserSessionDO;
-import org.apache.ibatis.annotations.Mapper;
-
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-
-@Mapper
-public interface UserSessionMapper extends BaseMapperX<UserSessionDO> {
-
-    default PageResult<UserSessionDO> selectPage(UserSessionPageReqVO reqVO, Collection<Long> userIds) {
-        return selectPage(reqVO, new LambdaQueryWrapperX<UserSessionDO>()
-                .inIfPresent(UserSessionDO::getUserId, userIds)
-                .likeIfPresent(UserSessionDO::getUserIp, reqVO.getUserIp()));
-    }
-
-    default List<UserSessionDO> selectListBySessionTimoutLt() {
-        return selectList(new LambdaQueryWrapperX<UserSessionDO>()
-                .lt(UserSessionDO::getSessionTimeout, new Date()));
-    }
-
-    default void updateByToken(String token, UserSessionDO updateObj) {
-        update(updateObj, new LambdaQueryWrapperX<UserSessionDO>()
-                .eq(UserSessionDO::getToken, token));
-    }
-
-    default void deleteByToken(String token) {
-        delete(new LambdaQueryWrapperX<UserSessionDO>().eq(UserSessionDO::getToken, token));
-    }
-
-}

+ 0 - 5
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/redis/RedisKeyConstants.java

@@ -1,7 +1,6 @@
 package cn.iocoder.yudao.module.system.dal.redis;
 
 import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
-import cn.iocoder.yudao.framework.security.core.LoginUser;
 import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
 
 import java.time.Duration;
@@ -19,10 +18,6 @@ public interface RedisKeyConstants {
             "captcha_code:%s", // 参数为 uuid
             STRING, String.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC);
 
-    RedisKeyDefine LOGIN_USER = new RedisKeyDefine("登录用户的缓存",
-            "login_user:%s", // 参数为 token 令牌
-            STRING, LoginUser.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC);
-
     RedisKeyDefine OAUTH2_ACCESS_TOKEN = new RedisKeyDefine("访问令牌的缓存",
             "oauth2_access_token:%s", // 参数为访问令牌 token
             STRING, OAuth2AccessTokenDO.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC);

+ 0 - 52
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/redis/auth/LoginUserRedisDAO.java

@@ -1,52 +0,0 @@
-package cn.iocoder.yudao.module.system.dal.redis.auth;
-
-import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
-import cn.iocoder.yudao.framework.security.config.SecurityProperties;
-import cn.iocoder.yudao.framework.security.core.LoginUser;
-import org.springframework.data.redis.core.StringRedisTemplate;
-import org.springframework.stereotype.Repository;
-
-import javax.annotation.Resource;
-
-import static cn.iocoder.yudao.module.system.dal.redis.RedisKeyConstants.LOGIN_USER;
-
-/**
- * {@link LoginUser} 的 RedisDAO
- *
- * @author 芋道源码
- */
-@Repository
-public class LoginUserRedisDAO {
-
-    @Resource
-    private StringRedisTemplate stringRedisTemplate;
-
-    @Resource
-    private SecurityProperties securityProperties;
-
-    public LoginUser get(String token) {
-        String redisKey = formatKey(token);
-        return JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(redisKey), LoginUser.class);
-    }
-
-    public Boolean exists(String token) {
-        String redisKey = formatKey(token);
-        return stringRedisTemplate.hasKey(redisKey);
-    }
-
-    public void set(String token, LoginUser loginUser) {
-        String redisKey = formatKey(token);
-        stringRedisTemplate.opsForValue().set(redisKey, JsonUtils.toJsonString(loginUser),
-                securityProperties.getSessionTimeout());
-    }
-
-    public void delete(String token) {
-        String redisKey = formatKey(token);
-        stringRedisTemplate.delete(redisKey);
-    }
-
-    private static String formatKey(String token) {
-        return LOGIN_USER.formatKey(token);
-    }
-
-}

+ 8 - 10
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthService.java

@@ -17,9 +17,9 @@ public interface AdminAuthService {
      * 账号登录
      *
      * @param reqVO 登录信息
-     * @return 身份令牌,使用 JWT 方式
+     * @return 登录结果
      */
-    String login(@Valid AuthLoginReqVO reqVO);
+    AuthLoginRespVO login(@Valid AuthLoginReqVO reqVO);
 
     /**
      * 基于 token 退出登录
@@ -39,26 +39,24 @@ public interface AdminAuthService {
      * 短信登录
      *
      * @param reqVO 登录信息
-     * @return 身份令牌,使用 JWT 方式
+     * @return 登录结果
      */
-    String smsLogin(AuthSmsLoginReqVO reqVO) ;
+    AuthLoginRespVO smsLogin(AuthSmsLoginReqVO reqVO) ;
 
     /**
      * 社交快捷登录,使用 code 授权码
      *
      * @param reqVO 登录信息
-     * @return 身份令牌,使用 JWT 方式
+     * @return 登录结果
      */
-    String socialQuickLogin(@Valid AuthSocialQuickLoginReqVO reqVO);
+    AuthLoginRespVO socialQuickLogin(@Valid AuthSocialQuickLoginReqVO reqVO);
 
     /**
      * 社交绑定登录,使用 code 授权码 + 账号密码
      *
      * @param reqVO 登录信息
-     * @param userIp 用户 IP
-     * @param userAgent 用户 UA
-     * @return 身份令牌,使用 JWT 方式
+     * @return 登录结果
      */
-    String socialBindLogin(@Valid AuthSocialBindLoginReqVO reqVO);
+    AuthLoginRespVO socialBindLogin(@Valid AuthSocialBindLoginReqVO reqVO);
 
 }

+ 10 - 8
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java

@@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.system.controller.admin.auth.vo.auth.*;
 import cn.iocoder.yudao.module.system.convert.auth.AuthConvert;
 import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
+import cn.iocoder.yudao.module.system.enums.auth.OAuth2ClientIdEnum;
 import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
 import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
 import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
@@ -58,7 +59,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
     private SmsCodeApi smsCodeApi;
 
     @Override
-    public String login(AuthLoginReqVO reqVO) {
+    public AuthLoginRespVO login(AuthLoginReqVO reqVO) {
         // 判断验证码是否正确
         verifyCaptcha(reqVO);
 
@@ -80,7 +81,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
     }
 
     @Override
-    public String smsLogin(AuthSmsLoginReqVO reqVO) {
+    public AuthLoginRespVO smsLogin(AuthSmsLoginReqVO reqVO) {
         // 校验验证码
         smsCodeApi.useSmsCode(AuthConvert.INSTANCE.convert(reqVO, SmsSceneEnum.ADMIN_MEMBER_LOGIN.getScene(), getClientIP()));
 
@@ -161,7 +162,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
     }
 
     @Override
-    public String socialQuickLogin(AuthSocialQuickLoginReqVO reqVO) {
+    public AuthLoginRespVO socialQuickLogin(AuthSocialQuickLoginReqVO reqVO) {
         // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号
         Long userId = socialUserService.getBindUserId(UserTypeEnum.ADMIN.getValue(), reqVO.getType(),
                 reqVO.getCode(), reqVO.getState());
@@ -180,7 +181,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
     }
 
     @Override
-    public String socialBindLogin(AuthSocialBindLoginReqVO reqVO) {
+    public AuthLoginRespVO socialBindLogin(AuthSocialBindLoginReqVO reqVO) {
         // 使用账号密码,进行登录。
         AdminUserDO user = login0(reqVO.getUsername(), reqVO.getPassword());
 
@@ -191,13 +192,14 @@ public class AdminAuthServiceImpl implements AdminAuthService {
         return createTokenAfterLoginSuccess(user.getId(), reqVO.getUsername(), LoginLogTypeEnum.LOGIN_SOCIAL);
     }
 
-    private String createTokenAfterLoginSuccess(Long userId, String username, LoginLogTypeEnum logType) {
+    private AuthLoginRespVO createTokenAfterLoginSuccess(Long userId, String username, LoginLogTypeEnum logType) {
         // 插入登陆日志
         createLoginLog(userId, username, logType, LoginResultEnum.SUCCESS);
         // 创建访问令牌
-        // TODO clientId
-        return oauth2TokenService.createAccessToken(userId, getUserType().getValue(), 1L)
-                .getAccessToken();
+        OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.createAccessToken(userId, getUserType().getValue(),
+                OAuth2ClientIdEnum.DEFAULT.getId());
+        // 构建返回结果
+        return AuthConvert.INSTANCE.convert(accessTokenDO);
     }
 
     @Override

+ 0 - 36
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/UserSessionService.java

@@ -1,36 +0,0 @@
-package cn.iocoder.yudao.module.system.service.auth;
-
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.system.controller.admin.auth.vo.session.UserSessionPageReqVO;
-import cn.iocoder.yudao.module.system.dal.dataobject.auth.UserSessionDO;
-
-/**
- * 在线用户 Session Service 接口
- *
- * @author 芋道源码
- */
-public interface UserSessionService {
-
-    /**
-     * 获得在线用户分页列表
-     *
-     * @param reqVO 分页条件
-     * @return 份额与列表
-     */
-    PageResult<UserSessionDO> getUserSessionPage(UserSessionPageReqVO reqVO);
-
-    /**
-     * 删除在线用户 Session
-     *
-     * @param token token 令牌
-     */
-    void deleteUserSession(String token);
-
-    /**
-     * 删除在线用户 Session
-     *
-     * @param id 编号
-     */
-    void deleteUserSession(Long id);
-
-}

+ 0 - 98
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/UserSessionServiceImpl.java

@@ -1,98 +0,0 @@
-package cn.iocoder.yudao.module.system.service.auth;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
-import cn.iocoder.yudao.framework.security.config.SecurityProperties;
-import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO;
-import cn.iocoder.yudao.module.system.controller.admin.auth.vo.session.UserSessionPageReqVO;
-import cn.iocoder.yudao.module.system.dal.dataobject.auth.UserSessionDO;
-import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
-import cn.iocoder.yudao.module.system.dal.mysql.auth.UserSessionMapper;
-import cn.iocoder.yudao.module.system.dal.redis.auth.LoginUserRedisDAO;
-import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
-import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
-import cn.iocoder.yudao.module.system.service.logger.LoginLogService;
-import cn.iocoder.yudao.module.system.service.user.AdminUserService;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-
-import javax.annotation.Resource;
-import java.util.Collection;
-
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
-
-/**
- * 在线用户 Session Service 实现类
- *
- * @author 芋道源码
- */
-@Slf4j
-@Service
-public class UserSessionServiceImpl implements UserSessionService {
-
-    @Resource
-    private UserSessionMapper userSessionMapper;
-
-    @Resource
-    private AdminUserService userService;
-    @Resource
-    private LoginLogService loginLogService;
-
-    @Resource
-    private LoginUserRedisDAO loginUserRedisDAO;
-
-    @Resource
-    private SecurityProperties securityProperties;
-
-    @Override
-    public PageResult<UserSessionDO> getUserSessionPage(UserSessionPageReqVO reqVO) {
-        // 处理基于用户昵称的查询
-        Collection<Long> userIds = null;
-        if (StrUtil.isNotEmpty(reqVO.getUsername())) {
-            userIds = convertSet(userService.getUsersByUsername(reqVO.getUsername()), AdminUserDO::getId);
-            if (CollUtil.isEmpty(userIds)) {
-                return PageResult.empty();
-            }
-        }
-        return userSessionMapper.selectPage(reqVO, userIds);
-    }
-
-    private void createLogoutLog(UserSessionDO session, LoginLogTypeEnum type) {
-        LoginLogCreateReqDTO reqDTO = new LoginLogCreateReqDTO();
-        reqDTO.setLogType(type.getType());
-        reqDTO.setTraceId(TracerUtils.getTraceId());
-        reqDTO.setUserId(session.getUserId());
-        reqDTO.setUserType(session.getUserType());
-        reqDTO.setUsername(session.getUsername());
-        reqDTO.setUserAgent(session.getUserAgent());
-        reqDTO.setUserIp(session.getUserIp());
-        reqDTO.setResult(LoginResultEnum.SUCCESS.getResult());
-        loginLogService.createLoginLog(reqDTO);
-    }
-
-    @Override
-    public void deleteUserSession(String token) {
-        // 删除 Redis 缓存
-        loginUserRedisDAO.delete(token);
-        // 删除 DB 记录
-        userSessionMapper.deleteByToken(token);
-        // 无需记录日志,因为退出那已经记录
-    }
-
-    @Override
-    public void deleteUserSession(Long id) {
-        UserSessionDO session = userSessionMapper.selectById(id);
-        if (session == null) {
-            return;
-        }
-        // 删除 Redis 缓存
-        loginUserRedisDAO.delete(session.getToken());
-        // 删除 DB 记录
-        userSessionMapper.deleteById(id);
-        // 记录退出日志
-        createLogoutLog(session, LoginLogTypeEnum.LOGOUT_DELETE);
-    }
-
-}

+ 28 - 19
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AuthServiceImplTest.java

@@ -1,11 +1,13 @@
 package cn.iocoder.yudao.module.system.service.auth;
 
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.security.core.LoginUser;
+import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
 import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
 import cn.iocoder.yudao.module.system.controller.admin.auth.vo.auth.AuthLoginReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.auth.vo.auth.AuthLoginRespVO;
+import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
 import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
 import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
@@ -26,7 +28,6 @@ import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServic
 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
-import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.*;
 
@@ -43,11 +44,11 @@ public class AuthServiceImplTest extends BaseDbUnitTest {
     @MockBean
     private LoginLogService loginLogService;
     @MockBean
-    private UserSessionService userSessionService;
-    @MockBean
     private SocialUserService socialService;
     @MockBean
     private SmsCodeApi smsCodeApi;
+    @MockBean
+    private OAuth2TokenService oauth2TokenService;
 
     @MockBean
     private Validator validator;
@@ -188,22 +189,20 @@ public class AuthServiceImplTest extends BaseDbUnitTest {
         // mock 验证码正确
         when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(reqVO.getCode());
         // mock user 数据
-        AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setUsername("test_username")
+        AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(1L).setUsername("test_username")
                 .setPassword("test_password").setStatus(CommonStatusEnum.ENABLE.getStatus()));
         when(userService.getUserByUsername(eq("test_username"))).thenReturn(user);
         // mock password 匹配
         when(userService.isPasswordMatch(eq("test_password"), eq(user.getPassword()))).thenReturn(true);
         // mock 缓存登录用户到 Redis
-        String token = randomString();
-//        when(userSessionService.createUserSession(argThat(argument -> {
-//            AssertUtils.assertPojoEquals(user, argument);
-//            return true;
-//        }), eq(userIp), eq(userAgent))).thenReturn(token);
-        // TODO 芋艿:oauth2
+        OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class, o -> o.setUserId(1L)
+                .setUserType(UserTypeEnum.ADMIN.getValue()));
+        when(oauth2TokenService.createAccessToken(eq(1L), eq(UserTypeEnum.ADMIN.getValue()), eq(1L)))
+                .thenReturn(accessTokenDO);
 
         // 调用, 并断言异常
-        String result = authService.login(reqVO);
-        assertEquals(token, result);
+        AuthLoginRespVO loginRespVO = authService.login(reqVO);
+        assertPojoEquals(accessTokenDO, loginRespVO);
         // 校验调用参数
         verify(loginLogService).createLoginLog(
             argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType())
@@ -216,18 +215,28 @@ public class AuthServiceImplTest extends BaseDbUnitTest {
     public void testLogout_success() {
         // 准备参数
         String token = randomString();
-        LoginUser loginUser = randomPojo(LoginUser.class);
         // mock
-//        when(userSessionService.getLoginUser(token)).thenReturn(loginUser);
-        // TODO @芋艿:oauth2
+        OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class, o -> o.setUserId(1L)
+                .setUserType(UserTypeEnum.ADMIN.getValue()));
+        when(oauth2TokenService.removeAccessToken(eq(token))).thenReturn(accessTokenDO);
+
         // 调用
         authService.logout(token);
         // 校验调用参数
-        verify(userSessionService, times(1)).deleteUserSession(token);
-        verify(loginLogService, times(1)).createLoginLog(
-            argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGOUT_SELF.getType())
+        verify(loginLogService).createLoginLog(argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGOUT_SELF.getType())
                     && o.getResult().equals(LoginResultEnum.SUCCESS.getResult()))
         );
     }
 
+    @Test
+    public void testLogout_fail() {
+        // 准备参数
+        String token = randomString();
+
+        // 调用
+        authService.logout(token);
+        // 校验调用参数
+        verify(loginLogService, never()).createLoginLog(any());
+    }
+
 }

+ 0 - 139
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/UserSessionServiceImplTest.java

@@ -1,139 +0,0 @@
-package cn.iocoder.yudao.module.system.service.auth;
-
-import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
-import cn.iocoder.yudao.framework.security.config.SecurityProperties;
-import cn.iocoder.yudao.framework.security.core.LoginUser;
-import cn.iocoder.yudao.framework.test.core.ut.BaseDbAndRedisUnitTest;
-import cn.iocoder.yudao.module.system.controller.admin.auth.vo.session.UserSessionPageReqVO;
-import cn.iocoder.yudao.module.system.dal.dataobject.auth.UserSessionDO;
-import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
-import cn.iocoder.yudao.module.system.dal.mysql.auth.UserSessionMapper;
-import cn.iocoder.yudao.module.system.dal.redis.auth.LoginUserRedisDAO;
-import cn.iocoder.yudao.module.system.enums.common.SexEnum;
-import cn.iocoder.yudao.module.system.service.logger.LoginLogService;
-import cn.iocoder.yudao.module.system.service.user.AdminUserService;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.context.annotation.Import;
-
-import javax.annotation.Resource;
-import java.time.Duration;
-
-import static cn.hutool.core.util.RandomUtil.randomEle;
-import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
-import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
-import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
-import static java.util.Collections.singletonList;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.when;
-
-/**
- * {@link UserSessionServiceImpl} 的单元测试
- *
- * @author Lyon
- */
-@Import({UserSessionServiceImpl.class, LoginUserRedisDAO.class})
-public class UserSessionServiceImplTest extends BaseDbAndRedisUnitTest {
-
-    @Resource
-    private UserSessionServiceImpl userSessionService;
-
-    @Resource
-    private UserSessionMapper userSessionMapper;
-
-    @MockBean
-    private AdminUserService userService;
-    @MockBean
-    private LoginLogService loginLogService;
-    @Resource
-    private LoginUserRedisDAO loginUserRedisDAO;
-
-    @MockBean
-    private SecurityProperties securityProperties;
-
-    @BeforeEach
-    public void setUp() {
-        when(securityProperties.getSessionTimeout()).thenReturn(Duration.ofDays(1L));
-    }
-
-    @Test
-    public void testGetUserSessionPage_success() {
-        // mock 数据
-        AdminUserDO dbUser = randomPojo(AdminUserDO.class, o -> {
-            o.setSex(randomEle(SexEnum.values()).getSex());
-            o.setStatus(CommonStatusEnum.ENABLE.getStatus());
-        });
-        when(userService.getUsersByUsername(eq(dbUser.getUsername()))).thenReturn(singletonList(dbUser));
-        // 插入可被查询到的数据
-        String userIp = randomString();
-        UserSessionDO dbSession = randomPojo(UserSessionDO.class, o -> {
-            o.setUserId(dbUser.getId());
-            o.setUserType(randomEle(UserTypeEnum.values()).getValue());
-            o.setUserIp(userIp);
-        });
-        userSessionMapper.insert(dbSession);
-        // 测试 username 不匹配
-        userSessionMapper.insert(ObjectUtils.cloneIgnoreId(dbSession, o -> o.setUserId(123456L)));
-        // 测试 userIp 不匹配
-        userSessionMapper.insert(ObjectUtils.cloneIgnoreId(dbSession, o -> o.setUserIp("testUserIp")));
-        // 准备参数
-        UserSessionPageReqVO reqVO = new UserSessionPageReqVO();
-        reqVO.setUsername(dbUser.getUsername());
-        reqVO.setUserIp(userIp);
-
-        // 调用
-        PageResult<UserSessionDO> pageResult = userSessionService.getUserSessionPage(reqVO);
-        // 断言
-        assertEquals(1, pageResult.getTotal());
-        assertEquals(1, pageResult.getList().size());
-        assertPojoEquals(dbSession, pageResult.getList().get(0));
-    }
-
-    @Test
-    public void testDeleteUserSession_Token() {
-        // 准备参数
-        String token = randomString();
-
-        // mock redis 数据
-        loginUserRedisDAO.set(token, new LoginUser());
-        // mock db 数据
-        UserSessionDO userSession = randomPojo(UserSessionDO.class, o -> {
-            o.setUserType(randomEle(UserTypeEnum.values()).getValue());
-            o.setToken(token);
-        });
-        userSessionMapper.insert(userSession);
-
-        // 调用
-        userSessionService.deleteUserSession(token);
-        // 校验数据不存在了
-        assertNull(loginUserRedisDAO.get(token));
-        assertNull(userSessionMapper.selectOne(UserSessionDO::getToken, token));
-    }
-
-    @Test
-    public void testDeleteUserSession_Id() {
-        // mock db 数据
-        UserSessionDO userSession = randomPojo(UserSessionDO.class, o -> {
-            o.setUserType(randomEle(UserTypeEnum.values()).getValue());
-        });
-        userSessionMapper.insert(userSession);
-        // mock redis 数据
-        loginUserRedisDAO.set(userSession.getToken(), new LoginUser());
-
-        // 准备参数
-        Long id = userSession.getId();
-
-        // 调用
-        userSessionService.deleteUserSession(id);
-        // 校验数据不存在了
-        assertNull(loginUserRedisDAO.get(userSession.getToken()));
-        assertNull(userSessionMapper.selectById(id));
-    }
-
-}

+ 2 - 2
yudao-ui-admin/src/components/Editor/index.vue

@@ -22,7 +22,7 @@ import Quill from "quill";
 import "quill/dist/quill.core.css";
 import "quill/dist/quill.snow.css";
 import "quill/dist/quill.bubble.css";
-import { getToken } from "@/utils/auth";
+import { getAccessToken } from "@/utils/auth";
 
 export default {
   name: "Editor",
@@ -62,7 +62,7 @@ export default {
     return {
       uploadUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
       headers: {
-        Authorization: "Bearer " + getToken()
+        Authorization: "Bearer " + getAccessToken()
       },
       Quill: null,
       currentValue: "",

+ 2 - 2
yudao-ui-admin/src/components/FileUpload/index.vue

@@ -40,7 +40,7 @@
 </template>
 
 <script>
-import { getToken } from "@/utils/auth";
+import { getAccessToken } from "@/utils/auth";
 
 export default {
   name: "FileUpload",
@@ -75,7 +75,7 @@ export default {
       baseUrl: process.env.VUE_APP_BASE_API,
       uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
       headers: {
-        Authorization: "Bearer " + getToken(),
+        Authorization: "Bearer " + getAccessToken(),
       },
       fileList: [],
     };

+ 2 - 2
yudao-ui-admin/src/components/ImageUpload/index.vue

@@ -43,7 +43,7 @@
 </template>
 
 <script>
-import { getToken } from "@/utils/auth";
+import { getAccessToken } from "@/utils/auth";
 
 export default {
   props: {
@@ -79,7 +79,7 @@ export default {
       baseUrl: process.env.VUE_APP_BASE_API,
       uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
       headers: {
-        Authorization: "Bearer " + getToken(),
+        Authorization: "Bearer " + getAccessToken(),
       },
       fileList: []
     };

+ 3 - 3
yudao-ui-admin/src/components/UploadImage/index.vue

@@ -18,7 +18,7 @@
 </template>
 
 <script>
-import { getToken } from "@/utils/auth";
+import { getAccessToken } from "@/utils/auth";
 
 export default {
   components: {},
@@ -26,7 +26,7 @@ export default {
     return {
       uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
       headers: {
-        Authorization: "Bearer " + getToken(),
+        Authorization: "Bearer " + getAccessToken(),
       },
     };
   },
@@ -65,4 +65,4 @@ export default {
   width: 100%;
   height: 100%;
 }
-</style>
+</style>

+ 2 - 2
yudao-ui-admin/src/permission.js

@@ -3,7 +3,7 @@ import store from './store'
 import { Message } from 'element-ui'
 import NProgress from 'nprogress'
 import 'nprogress/nprogress.css'
-import { getToken } from '@/utils/auth'
+import { getAccessToken } from '@/utils/auth'
 import { isRelogin } from '@/utils/request'
 
 NProgress.configure({ showSpinner: false })
@@ -13,7 +13,7 @@ const whiteList = ['/login', '/social-login',  '/auth-redirect', '/bind', '/regi
 
 router.beforeEach((to, from, next) => {
   NProgress.start()
-  if (getToken()) {
+  if (getAccessToken()) {
     to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
     /* has token*/
     if (to.path === '/login') {

+ 17 - 20
yudao-ui-admin/src/store/modules/user.js

@@ -1,9 +1,10 @@
 import {login, logout, getInfo, socialQuickLogin, socialBindLogin, smsLogin} from '@/api/login'
-import { getToken, setToken, removeToken } from '@/utils/auth'
+import {getAccessToken, setToken, removeToken, getRefreshToken} from '@/utils/auth'
 
 const user = {
   state: {
-    token: getToken(),
+    accessToken: getAccessToken(),
+    refreshToken: getRefreshToken(),
     id: 0, // 用户编号
     name: '',
     avatar: '',
@@ -16,7 +17,8 @@ const user = {
       state.id = id
     },
     SET_TOKEN: (state, token) => {
-      state.token = token
+      state.accessToken = token.accessToken
+      state.refreshToken = token.refreshToken
     },
     SET_NAME: (state, name) => {
       state.name = name
@@ -42,8 +44,9 @@ const user = {
       return new Promise((resolve, reject) => {
         login(username, password, code, uuid).then(res => {
           res = res.data;
-          setToken(res.token)
-          commit('SET_TOKEN', res.token)
+          // 设置 token
+          setToken(res)
+          commit('SET_TOKEN', res)
           resolve()
         }).catch(error => {
           reject(error)
@@ -59,8 +62,9 @@ const user = {
       return new Promise((resolve, reject) => {
         socialQuickLogin(type, code, state).then(res => {
           res = res.data;
-          setToken(res.token)
-          commit('SET_TOKEN', res.token)
+          // 设置 token
+          setToken(res)
+          commit('SET_TOKEN', res)
           resolve()
         }).catch(error => {
           reject(error)
@@ -78,8 +82,9 @@ const user = {
       return new Promise((resolve, reject) => {
         socialBindLogin(type, code, state, username, password).then(res => {
           res = res.data;
-          setToken(res.token)
-          commit('SET_TOKEN', res.token)
+          // 设置 token
+          setToken(res)
+          commit('SET_TOKEN', res)
           resolve()
         }).catch(error => {
           reject(error)
@@ -93,8 +98,9 @@ const user = {
       return new Promise((resolve, reject) => {
         smsLogin(mobile,mobileCode).then(res => {
           res = res.data;
-          setToken(res.token)
-          commit('SET_TOKEN', res.token)
+          // 设置 token
+          setToken(res)
+          commit('SET_TOKEN', res)
           resolve()
         }).catch(error => {
           reject(error)
@@ -151,15 +157,6 @@ const user = {
           reject(error)
         })
       })
-    },
-
-    // 前端 登出
-    FedLogOut({ commit }) {
-      return new Promise(resolve => {
-        commit('SET_TOKEN', '')
-        removeToken()
-        resolve()
-      })
     }
   }
 }

+ 12 - 5
yudao-ui-admin/src/utils/auth.js

@@ -1,15 +1,22 @@
 import Cookies from 'js-cookie'
 
-const TokenKey = 'Admin-Token'
+const AccessTokenKey = 'ACCESS_TOKEN'
+const RefreshTokenKey = 'REFRESH_TOKEN'
 
-export function getToken() {
-  return Cookies.get(TokenKey)
+export function getAccessToken() {
+  return Cookies.get(AccessTokenKey)
+}
+
+export function getRefreshToken() {
+  return Cookies.get(AccessTokenKey)
 }
 
 export function setToken(token) {
-  return Cookies.set(TokenKey, token)
+  Cookies.set(AccessTokenKey, token.accessToken)
+  Cookies.set(RefreshTokenKey, token.refreshToken)
 }
 
 export function removeToken() {
-  return Cookies.remove(TokenKey)
+  Cookies.remove(AccessTokenKey)
+  Cookies.remove(RefreshTokenKey)
 }

+ 4 - 4
yudao-ui-admin/src/utils/request.js

@@ -1,7 +1,7 @@
 import axios from 'axios'
 import { Notification, MessageBox, Message } from 'element-ui'
 import store from '@/store'
-import { getToken } from '@/utils/auth'
+import { getAccessToken } from '@/utils/auth'
 import errorCode from '@/utils/errorCode'
 import Cookies from "js-cookie";
 import {getPath, getTenantEnable} from "@/utils/ruoyi";
@@ -21,8 +21,8 @@ const service = axios.create({
 service.interceptors.request.use(config => {
   // 是否需要设置 token
   const isToken = (config.headers || {}).isToken === false
-  if (getToken() && !isToken) {
-    config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
+  if (getAccessToken() && !isToken) {
+    config.headers['Authorization'] = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token 请根据实际情况自行修改
   }
   // 设置租户
   if (getTenantEnable()) {
@@ -133,7 +133,7 @@ service.interceptors.response.use(res => {
 
 export function getBaseHeader() {
   return {
-    'Authorization': "Bearer " + getToken(),
+    'Authorization': "Bearer " + getAccessToken(),
     'tenant-id': Cookies.get('tenantId'),
   }
 }

+ 2 - 2
yudao-ui-admin/src/views/infra/file/index.vue

@@ -77,7 +77,7 @@
 
 <script>
 import { deleteFile, getFilePage } from "@/api/infra/file";
-import {getToken} from "@/utils/auth";
+import {getAccessToken} from "@/utils/auth";
 
 export default {
   name: "File",
@@ -108,7 +108,7 @@ export default {
         title: "", // 弹出层标题
         isUploading: false, // 是否禁用上传
         url: process.env.VUE_APP_BASE_API + "/admin-api/infra/file/upload", // 请求地址
-        headers: { Authorization: "Bearer " + getToken() }, // 设置上传的请求头部
+        headers: { Authorization: "Bearer " + getAccessToken() }, // 设置上传的请求头部
         data: {} // 上传的额外数据,用于文件名
       },
     };

+ 1 - 1
yudao-ui-admin/src/views/system/user/index.vue

@@ -237,7 +237,7 @@ import {
   resetUserPwd,
   updateUser
 } from "@/api/system/user";
-import {getToken} from "@/utils/auth";
+import {getAccessToken} from "@/utils/auth";
 import Treeselect from "@riophae/vue-treeselect";
 import "@riophae/vue-treeselect/dist/vue-treeselect.css";