登录后,返回 OAuth2 的 access token + refresh token
parent
5ea9cc3cd7
commit
86e6c04e07
@ -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;
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -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);
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@ -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)
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue