登录后,返回 OAuth2 的 access token + refresh token
This commit is contained in:
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;
|
||||||
|
|
||||||
|
}
|
|
@ -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.OAuth2AccessTokenCheckRespDTO;
|
||||||
import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenCreateReqDTO;
|
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.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 cn.iocoder.yudao.module.system.service.auth.OAuth2TokenService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ public class OAuth2TokenApiImpl implements OAuth2TokenApi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OAuth2AccessTokenCheckRespDTO checkAccessToken(String accessToken) {
|
public OAuth2AccessTokenCheckRespDTO checkAccessToken(String accessToken) {
|
||||||
return UserSessionConvert.INSTANCE.convert(oauth2TokenService.checkAccessToken(accessToken));
|
return OAuth2TokenConvert.INSTANCE.convert(oauth2TokenService.checkAccessToken(accessToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,8 +61,7 @@ public class AuthController {
|
||||||
@ApiOperation("使用账号密码登录")
|
@ApiOperation("使用账号密码登录")
|
||||||
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
||||||
public CommonResult<AuthLoginRespVO> login(@RequestBody @Valid AuthLoginReqVO reqVO) {
|
public CommonResult<AuthLoginRespVO> login(@RequestBody @Valid AuthLoginReqVO reqVO) {
|
||||||
String token = authService.login(reqVO);
|
return success(authService.login(reqVO));
|
||||||
return success(AuthLoginRespVO.builder().token(token).build());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/logout")
|
@PostMapping("/logout")
|
||||||
|
@ -114,9 +113,7 @@ public class AuthController {
|
||||||
@ApiOperation("使用短信验证码登录")
|
@ApiOperation("使用短信验证码登录")
|
||||||
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
||||||
public CommonResult<AuthLoginRespVO> smsLogin(@RequestBody @Valid AuthSmsLoginReqVO reqVO) {
|
public CommonResult<AuthLoginRespVO> smsLogin(@RequestBody @Valid AuthSmsLoginReqVO reqVO) {
|
||||||
String token = authService.smsLogin(reqVO);
|
return success(authService.smsLogin(reqVO));
|
||||||
// 返回结果
|
|
||||||
return success(AuthLoginRespVO.builder().token(token).build());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/send-sms-code")
|
@PostMapping("/send-sms-code")
|
||||||
|
@ -144,16 +141,14 @@ public class AuthController {
|
||||||
@ApiOperation("社交快捷登录,使用 code 授权码")
|
@ApiOperation("社交快捷登录,使用 code 授权码")
|
||||||
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
||||||
public CommonResult<AuthLoginRespVO> socialQuickLogin(@RequestBody @Valid AuthSocialQuickLoginReqVO reqVO) {
|
public CommonResult<AuthLoginRespVO> socialQuickLogin(@RequestBody @Valid AuthSocialQuickLoginReqVO reqVO) {
|
||||||
String token = authService.socialQuickLogin(reqVO);
|
return success(authService.socialQuickLogin(reqVO));
|
||||||
return success(AuthLoginRespVO.builder().token(token).build());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/social-bind-login")
|
@PostMapping("/social-bind-login")
|
||||||
@ApiOperation("社交绑定登录,使用 code 授权码 + 账号密码")
|
@ApiOperation("社交绑定登录,使用 code 授权码 + 账号密码")
|
||||||
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
|
||||||
public CommonResult<AuthLoginRespVO> socialBindLogin(@RequestBody @Valid AuthSocialBindLoginReqVO reqVO) {
|
public CommonResult<AuthLoginRespVO> socialBindLogin(@RequestBody @Valid AuthSocialBindLoginReqVO reqVO) {
|
||||||
String token = authService.socialBindLogin(reqVO);
|
return success(authService.socialBindLogin(reqVO));
|
||||||
return success(AuthLoginRespVO.builder().token(token).build());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -7,14 +7,25 @@ import lombok.Builder;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
@ApiModel("管理后台 - 账号密码登录 Response VO")
|
import java.util.Date;
|
||||||
|
|
||||||
|
@ApiModel("管理后台 - 登录 Response VO")
|
||||||
@Data
|
@Data
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@Builder
|
@Builder
|
||||||
public class AuthLoginRespVO {
|
public class AuthLoginRespVO {
|
||||||
|
|
||||||
@ApiModelProperty(value = "token", required = true, example = "yudaoyuanma")
|
@ApiModelProperty(value = "用户编号", required = true, example = "1024")
|
||||||
private String token;
|
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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,11 +1,11 @@
|
||||||
package cn.iocoder.yudao.module.system.convert.auth;
|
package cn.iocoder.yudao.module.system.convert.auth;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
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.SmsCodeSendReqDTO;
|
||||||
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
|
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.api.social.dto.SocialUserBindReqDTO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.auth.vo.auth.*;
|
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.MenuDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||||
|
@ -21,7 +21,7 @@ public interface AuthConvert {
|
||||||
|
|
||||||
AuthConvert INSTANCE = Mappers.getMapper(AuthConvert.class);
|
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) {
|
default AuthPermissionInfoRespVO convert(AdminUserDO user, List<RoleDO> roleList, List<MenuDO> menuList) {
|
||||||
return AuthPermissionInfoRespVO.builder()
|
return AuthPermissionInfoRespVO.builder()
|
||||||
|
|
|
@ -1,18 +1,14 @@
|
||||||
package cn.iocoder.yudao.module.system.convert.auth;
|
package cn.iocoder.yudao.module.system.convert.auth;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.system.api.auth.dto.OAuth2AccessTokenCheckRespDTO;
|
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.OAuth2AccessTokenDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.auth.UserSessionDO;
|
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface UserSessionConvert {
|
public interface OAuth2TokenConvert {
|
||||||
|
|
||||||
UserSessionConvert INSTANCE = Mappers.getMapper(UserSessionConvert.class);
|
OAuth2TokenConvert INSTANCE = Mappers.getMapper(OAuth2TokenConvert.class);
|
||||||
|
|
||||||
UserSessionPageItemRespVO convert(UserSessionDO session);
|
|
||||||
|
|
||||||
OAuth2AccessTokenCheckRespDTO convert(OAuth2AccessTokenDO bean);
|
OAuth2AccessTokenCheckRespDTO convert(OAuth2AccessTokenDO bean);
|
||||||
|
|
|
@ -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;
|
|
||||||
|
|
||||||
}
|
|
|
@ -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,7 +1,6 @@
|
||||||
package cn.iocoder.yudao.module.system.dal.redis;
|
package cn.iocoder.yudao.module.system.dal.redis;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
|
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 cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
@ -19,10 +18,6 @@ public interface RedisKeyConstants {
|
||||||
"captcha_code:%s", // 参数为 uuid
|
"captcha_code:%s", // 参数为 uuid
|
||||||
STRING, String.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC);
|
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("访问令牌的缓存",
|
RedisKeyDefine OAUTH2_ACCESS_TOKEN = new RedisKeyDefine("访问令牌的缓存",
|
||||||
"oauth2_access_token:%s", // 参数为访问令牌 token
|
"oauth2_access_token:%s", // 参数为访问令牌 token
|
||||||
STRING, OAuth2AccessTokenDO.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC);
|
STRING, OAuth2AccessTokenDO.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC);
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -17,9 +17,9 @@ public interface AdminAuthService {
|
||||||
* 账号登录
|
* 账号登录
|
||||||
*
|
*
|
||||||
* @param reqVO 登录信息
|
* @param reqVO 登录信息
|
||||||
* @return 身份令牌,使用 JWT 方式
|
* @return 登录结果
|
||||||
*/
|
*/
|
||||||
String login(@Valid AuthLoginReqVO reqVO);
|
AuthLoginRespVO login(@Valid AuthLoginReqVO reqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基于 token 退出登录
|
* 基于 token 退出登录
|
||||||
|
@ -39,26 +39,24 @@ public interface AdminAuthService {
|
||||||
* 短信登录
|
* 短信登录
|
||||||
*
|
*
|
||||||
* @param reqVO 登录信息
|
* @param reqVO 登录信息
|
||||||
* @return 身份令牌,使用 JWT 方式
|
* @return 登录结果
|
||||||
*/
|
*/
|
||||||
String smsLogin(AuthSmsLoginReqVO reqVO) ;
|
AuthLoginRespVO smsLogin(AuthSmsLoginReqVO reqVO) ;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 社交快捷登录,使用 code 授权码
|
* 社交快捷登录,使用 code 授权码
|
||||||
*
|
*
|
||||||
* @param reqVO 登录信息
|
* @param reqVO 登录信息
|
||||||
* @return 身份令牌,使用 JWT 方式
|
* @return 登录结果
|
||||||
*/
|
*/
|
||||||
String socialQuickLogin(@Valid AuthSocialQuickLoginReqVO reqVO);
|
AuthLoginRespVO socialQuickLogin(@Valid AuthSocialQuickLoginReqVO reqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 社交绑定登录,使用 code 授权码 + 账号密码
|
* 社交绑定登录,使用 code 授权码 + 账号密码
|
||||||
*
|
*
|
||||||
* @param reqVO 登录信息
|
* @param reqVO 登录信息
|
||||||
* @param userIp 用户 IP
|
* @return 登录结果
|
||||||
* @param userAgent 用户 UA
|
|
||||||
* @return 身份令牌,使用 JWT 方式
|
|
||||||
*/
|
*/
|
||||||
String socialBindLogin(@Valid AuthSocialBindLoginReqVO reqVO);
|
AuthLoginRespVO socialBindLogin(@Valid AuthSocialBindLoginReqVO reqVO);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.convert.auth.AuthConvert;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.auth.OAuth2AccessTokenDO;
|
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.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.LoginLogTypeEnum;
|
||||||
import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
|
import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
|
||||||
import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
|
import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
|
||||||
|
@ -58,7 +59,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
||||||
private SmsCodeApi smsCodeApi;
|
private SmsCodeApi smsCodeApi;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String login(AuthLoginReqVO reqVO) {
|
public AuthLoginRespVO login(AuthLoginReqVO reqVO) {
|
||||||
// 判断验证码是否正确
|
// 判断验证码是否正确
|
||||||
verifyCaptcha(reqVO);
|
verifyCaptcha(reqVO);
|
||||||
|
|
||||||
|
@ -80,7 +81,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String smsLogin(AuthSmsLoginReqVO reqVO) {
|
public AuthLoginRespVO smsLogin(AuthSmsLoginReqVO reqVO) {
|
||||||
// 校验验证码
|
// 校验验证码
|
||||||
smsCodeApi.useSmsCode(AuthConvert.INSTANCE.convert(reqVO, SmsSceneEnum.ADMIN_MEMBER_LOGIN.getScene(), getClientIP()));
|
smsCodeApi.useSmsCode(AuthConvert.INSTANCE.convert(reqVO, SmsSceneEnum.ADMIN_MEMBER_LOGIN.getScene(), getClientIP()));
|
||||||
|
|
||||||
|
@ -161,7 +162,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String socialQuickLogin(AuthSocialQuickLoginReqVO reqVO) {
|
public AuthLoginRespVO socialQuickLogin(AuthSocialQuickLoginReqVO reqVO) {
|
||||||
// 使用 code 授权码,进行登录。然后,获得到绑定的用户编号
|
// 使用 code 授权码,进行登录。然后,获得到绑定的用户编号
|
||||||
Long userId = socialUserService.getBindUserId(UserTypeEnum.ADMIN.getValue(), reqVO.getType(),
|
Long userId = socialUserService.getBindUserId(UserTypeEnum.ADMIN.getValue(), reqVO.getType(),
|
||||||
reqVO.getCode(), reqVO.getState());
|
reqVO.getCode(), reqVO.getState());
|
||||||
|
@ -180,7 +181,7 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String socialBindLogin(AuthSocialBindLoginReqVO reqVO) {
|
public AuthLoginRespVO socialBindLogin(AuthSocialBindLoginReqVO reqVO) {
|
||||||
// 使用账号密码,进行登录。
|
// 使用账号密码,进行登录。
|
||||||
AdminUserDO user = login0(reqVO.getUsername(), reqVO.getPassword());
|
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);
|
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);
|
createLoginLog(userId, username, logType, LoginResultEnum.SUCCESS);
|
||||||
// 创建访问令牌
|
// 创建访问令牌
|
||||||
// TODO clientId
|
OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.createAccessToken(userId, getUserType().getValue(),
|
||||||
return oauth2TokenService.createAccessToken(userId, getUserType().getValue(), 1L)
|
OAuth2ClientIdEnum.DEFAULT.getId());
|
||||||
.getAccessToken();
|
// 构建返回结果
|
||||||
|
return AuthConvert.INSTANCE.convert(accessTokenDO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -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,11 +1,13 @@
|
||||||
package cn.iocoder.yudao.module.system.service.auth;
|
package cn.iocoder.yudao.module.system.service.auth;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
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.ut.BaseDbUnitTest;
|
||||||
import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
|
import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
|
||||||
import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
|
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.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.dal.dataobject.user.AdminUserDO;
|
||||||
import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
|
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.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.randomPojo;
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
|
||||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
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.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
@ -43,11 +44,11 @@ public class AuthServiceImplTest extends BaseDbUnitTest {
|
||||||
@MockBean
|
@MockBean
|
||||||
private LoginLogService loginLogService;
|
private LoginLogService loginLogService;
|
||||||
@MockBean
|
@MockBean
|
||||||
private UserSessionService userSessionService;
|
|
||||||
@MockBean
|
|
||||||
private SocialUserService socialService;
|
private SocialUserService socialService;
|
||||||
@MockBean
|
@MockBean
|
||||||
private SmsCodeApi smsCodeApi;
|
private SmsCodeApi smsCodeApi;
|
||||||
|
@MockBean
|
||||||
|
private OAuth2TokenService oauth2TokenService;
|
||||||
|
|
||||||
@MockBean
|
@MockBean
|
||||||
private Validator validator;
|
private Validator validator;
|
||||||
|
@ -188,22 +189,20 @@ public class AuthServiceImplTest extends BaseDbUnitTest {
|
||||||
// mock 验证码正确
|
// mock 验证码正确
|
||||||
when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(reqVO.getCode());
|
when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(reqVO.getCode());
|
||||||
// mock user 数据
|
// 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()));
|
.setPassword("test_password").setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||||
when(userService.getUserByUsername(eq("test_username"))).thenReturn(user);
|
when(userService.getUserByUsername(eq("test_username"))).thenReturn(user);
|
||||||
// mock password 匹配
|
// mock password 匹配
|
||||||
when(userService.isPasswordMatch(eq("test_password"), eq(user.getPassword()))).thenReturn(true);
|
when(userService.isPasswordMatch(eq("test_password"), eq(user.getPassword()))).thenReturn(true);
|
||||||
// mock 缓存登录用户到 Redis
|
// mock 缓存登录用户到 Redis
|
||||||
String token = randomString();
|
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class, o -> o.setUserId(1L)
|
||||||
// when(userSessionService.createUserSession(argThat(argument -> {
|
.setUserType(UserTypeEnum.ADMIN.getValue()));
|
||||||
// AssertUtils.assertPojoEquals(user, argument);
|
when(oauth2TokenService.createAccessToken(eq(1L), eq(UserTypeEnum.ADMIN.getValue()), eq(1L)))
|
||||||
// return true;
|
.thenReturn(accessTokenDO);
|
||||||
// }), eq(userIp), eq(userAgent))).thenReturn(token);
|
|
||||||
// TODO 芋艿:oauth2
|
|
||||||
|
|
||||||
// 调用, 并断言异常
|
// 调用, 并断言异常
|
||||||
String result = authService.login(reqVO);
|
AuthLoginRespVO loginRespVO = authService.login(reqVO);
|
||||||
assertEquals(token, result);
|
assertPojoEquals(accessTokenDO, loginRespVO);
|
||||||
// 校验调用参数
|
// 校验调用参数
|
||||||
verify(loginLogService).createLoginLog(
|
verify(loginLogService).createLoginLog(
|
||||||
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType())
|
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType())
|
||||||
|
@ -216,18 +215,28 @@ public class AuthServiceImplTest extends BaseDbUnitTest {
|
||||||
public void testLogout_success() {
|
public void testLogout_success() {
|
||||||
// 准备参数
|
// 准备参数
|
||||||
String token = randomString();
|
String token = randomString();
|
||||||
LoginUser loginUser = randomPojo(LoginUser.class);
|
|
||||||
// mock
|
// mock
|
||||||
// when(userSessionService.getLoginUser(token)).thenReturn(loginUser);
|
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class, o -> o.setUserId(1L)
|
||||||
// TODO @芋艿:oauth2
|
.setUserType(UserTypeEnum.ADMIN.getValue()));
|
||||||
|
when(oauth2TokenService.removeAccessToken(eq(token))).thenReturn(accessTokenDO);
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
authService.logout(token);
|
authService.logout(token);
|
||||||
// 校验调用参数
|
// 校验调用参数
|
||||||
verify(userSessionService, times(1)).deleteUserSession(token);
|
verify(loginLogService).createLoginLog(argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGOUT_SELF.getType())
|
||||||
verify(loginLogService, times(1)).createLoginLog(
|
|
||||||
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGOUT_SELF.getType())
|
|
||||||
&& o.getResult().equals(LoginResultEnum.SUCCESS.getResult()))
|
&& o.getResult().equals(LoginResultEnum.SUCCESS.getResult()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLogout_fail() {
|
||||||
|
// 准备参数
|
||||||
|
String token = randomString();
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
authService.logout(token);
|
||||||
|
// 校验调用参数
|
||||||
|
verify(loginLogService, never()).createLoginLog(any());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -22,7 +22,7 @@ import Quill from "quill";
|
||||||
import "quill/dist/quill.core.css";
|
import "quill/dist/quill.core.css";
|
||||||
import "quill/dist/quill.snow.css";
|
import "quill/dist/quill.snow.css";
|
||||||
import "quill/dist/quill.bubble.css";
|
import "quill/dist/quill.bubble.css";
|
||||||
import { getToken } from "@/utils/auth";
|
import { getAccessToken } from "@/utils/auth";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Editor",
|
name: "Editor",
|
||||||
|
@ -62,7 +62,7 @@ export default {
|
||||||
return {
|
return {
|
||||||
uploadUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
|
uploadUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: "Bearer " + getToken()
|
Authorization: "Bearer " + getAccessToken()
|
||||||
},
|
},
|
||||||
Quill: null,
|
Quill: null,
|
||||||
currentValue: "",
|
currentValue: "",
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getToken } from "@/utils/auth";
|
import { getAccessToken } from "@/utils/auth";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "FileUpload",
|
name: "FileUpload",
|
||||||
|
@ -75,7 +75,7 @@ export default {
|
||||||
baseUrl: process.env.VUE_APP_BASE_API,
|
baseUrl: process.env.VUE_APP_BASE_API,
|
||||||
uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
|
uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: "Bearer " + getToken(),
|
Authorization: "Bearer " + getAccessToken(),
|
||||||
},
|
},
|
||||||
fileList: [],
|
fileList: [],
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getToken } from "@/utils/auth";
|
import { getAccessToken } from "@/utils/auth";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
@ -79,7 +79,7 @@ export default {
|
||||||
baseUrl: process.env.VUE_APP_BASE_API,
|
baseUrl: process.env.VUE_APP_BASE_API,
|
||||||
uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
|
uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: "Bearer " + getToken(),
|
Authorization: "Bearer " + getAccessToken(),
|
||||||
},
|
},
|
||||||
fileList: []
|
fileList: []
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getToken } from "@/utils/auth";
|
import { getAccessToken } from "@/utils/auth";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
|
@ -26,7 +26,7 @@ export default {
|
||||||
return {
|
return {
|
||||||
uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
|
uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: "Bearer " + getToken(),
|
Authorization: "Bearer " + getAccessToken(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -65,4 +65,4 @@ export default {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -3,7 +3,7 @@ import store from './store'
|
||||||
import { Message } from 'element-ui'
|
import { Message } from 'element-ui'
|
||||||
import NProgress from 'nprogress'
|
import NProgress from 'nprogress'
|
||||||
import 'nprogress/nprogress.css'
|
import 'nprogress/nprogress.css'
|
||||||
import { getToken } from '@/utils/auth'
|
import { getAccessToken } from '@/utils/auth'
|
||||||
import { isRelogin } from '@/utils/request'
|
import { isRelogin } from '@/utils/request'
|
||||||
|
|
||||||
NProgress.configure({ showSpinner: false })
|
NProgress.configure({ showSpinner: false })
|
||||||
|
@ -13,7 +13,7 @@ const whiteList = ['/login', '/social-login', '/auth-redirect', '/bind', '/regi
|
||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
NProgress.start()
|
NProgress.start()
|
||||||
if (getToken()) {
|
if (getAccessToken()) {
|
||||||
to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
|
to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
|
||||||
/* has token*/
|
/* has token*/
|
||||||
if (to.path === '/login') {
|
if (to.path === '/login') {
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import {login, logout, getInfo, socialQuickLogin, socialBindLogin, smsLogin} from '@/api/login'
|
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 = {
|
const user = {
|
||||||
state: {
|
state: {
|
||||||
token: getToken(),
|
accessToken: getAccessToken(),
|
||||||
|
refreshToken: getRefreshToken(),
|
||||||
id: 0, // 用户编号
|
id: 0, // 用户编号
|
||||||
name: '',
|
name: '',
|
||||||
avatar: '',
|
avatar: '',
|
||||||
|
@ -16,7 +17,8 @@ const user = {
|
||||||
state.id = id
|
state.id = id
|
||||||
},
|
},
|
||||||
SET_TOKEN: (state, token) => {
|
SET_TOKEN: (state, token) => {
|
||||||
state.token = token
|
state.accessToken = token.accessToken
|
||||||
|
state.refreshToken = token.refreshToken
|
||||||
},
|
},
|
||||||
SET_NAME: (state, name) => {
|
SET_NAME: (state, name) => {
|
||||||
state.name = name
|
state.name = name
|
||||||
|
@ -42,8 +44,9 @@ const user = {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
login(username, password, code, uuid).then(res => {
|
login(username, password, code, uuid).then(res => {
|
||||||
res = res.data;
|
res = res.data;
|
||||||
setToken(res.token)
|
// 设置 token
|
||||||
commit('SET_TOKEN', res.token)
|
setToken(res)
|
||||||
|
commit('SET_TOKEN', res)
|
||||||
resolve()
|
resolve()
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
reject(error)
|
reject(error)
|
||||||
|
@ -59,8 +62,9 @@ const user = {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
socialQuickLogin(type, code, state).then(res => {
|
socialQuickLogin(type, code, state).then(res => {
|
||||||
res = res.data;
|
res = res.data;
|
||||||
setToken(res.token)
|
// 设置 token
|
||||||
commit('SET_TOKEN', res.token)
|
setToken(res)
|
||||||
|
commit('SET_TOKEN', res)
|
||||||
resolve()
|
resolve()
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
reject(error)
|
reject(error)
|
||||||
|
@ -78,8 +82,9 @@ const user = {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
socialBindLogin(type, code, state, username, password).then(res => {
|
socialBindLogin(type, code, state, username, password).then(res => {
|
||||||
res = res.data;
|
res = res.data;
|
||||||
setToken(res.token)
|
// 设置 token
|
||||||
commit('SET_TOKEN', res.token)
|
setToken(res)
|
||||||
|
commit('SET_TOKEN', res)
|
||||||
resolve()
|
resolve()
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
reject(error)
|
reject(error)
|
||||||
|
@ -93,8 +98,9 @@ const user = {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
smsLogin(mobile,mobileCode).then(res => {
|
smsLogin(mobile,mobileCode).then(res => {
|
||||||
res = res.data;
|
res = res.data;
|
||||||
setToken(res.token)
|
// 设置 token
|
||||||
commit('SET_TOKEN', res.token)
|
setToken(res)
|
||||||
|
commit('SET_TOKEN', res)
|
||||||
resolve()
|
resolve()
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
reject(error)
|
reject(error)
|
||||||
|
@ -151,15 +157,6 @@ const user = {
|
||||||
reject(error)
|
reject(error)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
|
||||||
|
|
||||||
// 前端 登出
|
|
||||||
FedLogOut({ commit }) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
commit('SET_TOKEN', '')
|
|
||||||
removeToken()
|
|
||||||
resolve()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,22 @@
|
||||||
import Cookies from 'js-cookie'
|
import Cookies from 'js-cookie'
|
||||||
|
|
||||||
const TokenKey = 'Admin-Token'
|
const AccessTokenKey = 'ACCESS_TOKEN'
|
||||||
|
const RefreshTokenKey = 'REFRESH_TOKEN'
|
||||||
|
|
||||||
export function getToken() {
|
export function getAccessToken() {
|
||||||
return Cookies.get(TokenKey)
|
return Cookies.get(AccessTokenKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRefreshToken() {
|
||||||
|
return Cookies.get(AccessTokenKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setToken(token) {
|
export function setToken(token) {
|
||||||
return Cookies.set(TokenKey, token)
|
Cookies.set(AccessTokenKey, token.accessToken)
|
||||||
|
Cookies.set(RefreshTokenKey, token.refreshToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function removeToken() {
|
export function removeToken() {
|
||||||
return Cookies.remove(TokenKey)
|
Cookies.remove(AccessTokenKey)
|
||||||
|
Cookies.remove(RefreshTokenKey)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { Notification, MessageBox, Message } from 'element-ui'
|
import { Notification, MessageBox, Message } from 'element-ui'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
import { getToken } from '@/utils/auth'
|
import { getAccessToken } from '@/utils/auth'
|
||||||
import errorCode from '@/utils/errorCode'
|
import errorCode from '@/utils/errorCode'
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
import {getPath, getTenantEnable} from "@/utils/ruoyi";
|
import {getPath, getTenantEnable} from "@/utils/ruoyi";
|
||||||
|
@ -21,8 +21,8 @@ const service = axios.create({
|
||||||
service.interceptors.request.use(config => {
|
service.interceptors.request.use(config => {
|
||||||
// 是否需要设置 token
|
// 是否需要设置 token
|
||||||
const isToken = (config.headers || {}).isToken === false
|
const isToken = (config.headers || {}).isToken === false
|
||||||
if (getToken() && !isToken) {
|
if (getAccessToken() && !isToken) {
|
||||||
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
|
config.headers['Authorization'] = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||||
}
|
}
|
||||||
// 设置租户
|
// 设置租户
|
||||||
if (getTenantEnable()) {
|
if (getTenantEnable()) {
|
||||||
|
@ -133,7 +133,7 @@ service.interceptors.response.use(res => {
|
||||||
|
|
||||||
export function getBaseHeader() {
|
export function getBaseHeader() {
|
||||||
return {
|
return {
|
||||||
'Authorization': "Bearer " + getToken(),
|
'Authorization': "Bearer " + getAccessToken(),
|
||||||
'tenant-id': Cookies.get('tenantId'),
|
'tenant-id': Cookies.get('tenantId'),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { deleteFile, getFilePage } from "@/api/infra/file";
|
import { deleteFile, getFilePage } from "@/api/infra/file";
|
||||||
import {getToken} from "@/utils/auth";
|
import {getAccessToken} from "@/utils/auth";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "File",
|
name: "File",
|
||||||
|
@ -108,7 +108,7 @@ export default {
|
||||||
title: "", // 弹出层标题
|
title: "", // 弹出层标题
|
||||||
isUploading: false, // 是否禁用上传
|
isUploading: false, // 是否禁用上传
|
||||||
url: process.env.VUE_APP_BASE_API + "/admin-api/infra/file/upload", // 请求地址
|
url: process.env.VUE_APP_BASE_API + "/admin-api/infra/file/upload", // 请求地址
|
||||||
headers: { Authorization: "Bearer " + getToken() }, // 设置上传的请求头部
|
headers: { Authorization: "Bearer " + getAccessToken() }, // 设置上传的请求头部
|
||||||
data: {} // 上传的额外数据,用于文件名
|
data: {} // 上传的额外数据,用于文件名
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -237,7 +237,7 @@ import {
|
||||||
resetUserPwd,
|
resetUserPwd,
|
||||||
updateUser
|
updateUser
|
||||||
} from "@/api/system/user";
|
} from "@/api/system/user";
|
||||||
import {getToken} from "@/utils/auth";
|
import {getAccessToken} from "@/utils/auth";
|
||||||
import Treeselect from "@riophae/vue-treeselect";
|
import Treeselect from "@riophae/vue-treeselect";
|
||||||
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue