开始重构 system 模块的代码,先修改认证逻辑

This commit is contained in:
YunaiV
2020-04-17 19:25:24 +08:00
parent 233a441579
commit 4ffc2cb815
201 changed files with 1788 additions and 561 deletions

View File

@@ -0,0 +1,26 @@
package cn.iocoder.mall.system.biz.bo.account;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 账号信息 BO
*/
@Data
@Accessors(chain = true)
public class AccountBO {
/**
* 账号编号
*/
private Integer id;
/**
* 登陆账号
*/
private String username;
/**
* 登陆密码
*/
private String password;
}

View File

@@ -0,0 +1,22 @@
package cn.iocoder.mall.system.biz.bo.account;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 账号模块 - 用户名登陆 BO
*/
@Data
@Accessors(chain = true)
public class AccountUsernameAuthorizeBO {
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
}

View File

@@ -0,0 +1,22 @@
package cn.iocoder.mall.system.biz.bo.admin;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 管理员模块 - 账号信息 BO
*/
@Data
@Accessors(chain = true)
public class AdminBO {
/**
* 管理员编号
*/
private Integer id;
/**
* 真实名字
*/
private String name;
}

View File

@@ -0,0 +1,32 @@
package cn.iocoder.mall.system.biz.bo.ouath2;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* TODO 注释
*/
@Data
@Accessors(chain = true)
public class OAuth2AccessTokenBO {
/**
* 访问令牌
*/
private String id;
/**
* 刷新令牌
*/
private String refreshToken;
/**
* 账号编号
*/
private Integer accountId;
/**
* 过期时间
*/
private Date expiresTime;
}

View File

@@ -0,0 +1 @@
package cn.iocoder.mall.system.biz.bo;

View File

@@ -0,0 +1,28 @@
package cn.iocoder.mall.system.biz.config;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@MapperScan("cn.iocoder.mall.system.biz.dao") // 扫描对应的 Mapper 接口
@EnableTransactionManagement(proxyTargetClass = true) // 启动事务管理。为什么使用 proxyTargetClass 参数,参见 https://blog.csdn.net/huang_550/article/details/76492600
public class DatabaseConfiguration {
// 数据库连接池 Druid
@Bean
public ISqlInjector sqlInjector() {
return new DefaultSqlInjector(); // MyBatis Plus 逻辑删除
}
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor(); // MyBatis Plus 分页插件
}
}

View File

@@ -0,0 +1,19 @@
package cn.iocoder.mall.system.biz.config;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.mall.system.biz.constant.SystemErrorCodeEnum;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
@Configuration
public class ServiceExceptionConfiguration {
@EventListener(ApplicationReadyEvent.class) // 可参考 https://www.cnblogs.com/ssslinppp/p/7607509.html
public void initMessages() {
for (SystemErrorCodeEnum item : SystemErrorCodeEnum.values()) {
ServiceExceptionUtil.put(item.getCode(), item.getMessage());
}
}
}

View File

@@ -0,0 +1,91 @@
package cn.iocoder.mall.system.biz.constant;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
/**
* 错误码枚举类
*
* system 系统,使用 1-002-000-000 段
*/
public enum SystemErrorCodeEnum implements ServiceExceptionUtil.Enumerable {
// ========== OAUTH2 模块 ==========
OAUTH2_UNKNOWN(1001001000, "未知错误"), // 预留
OAUTH2_ACCOUNT_NOT_FOUND(1001001001, "账号不存在"),
OAUTH2_ACCOUNT_PASSWORD_ERROR(1001001002, "密码不正确"),
//// OAUTH2_INVALID_GRANT_USERNAME_NOT_FOUND(1001001002, "账号不存在"), // 暂时没用到
//// OAUTH2_INVALID_GRANT(1001001010, ""), // 预留
// OAUTH2_INVALID_TOKEN_NOT_FOUND(1002001011, "访问令牌不存在"),
// OAUTH2_INVALID_TOKEN_EXPIRED(1002001012, "访问令牌已过期"),
// OAUTH2_INVALID_TOKEN_INVALID(1002001013, "访问令牌已失效"),
// OAUTH2_NOT_LOGIN(1002001015, "账号未登陆"),
// OAUTH2_INVALID_TOKEN_ERROR_USER_TYPE(1002001016, "访问令牌用户类型不正确"),
// OAUTH_INVALID_REFRESH_TOKEN_NOT_FOUND(1002001017, "刷新令牌不存在"),
// OAUTH_INVALID_REFRESH_TOKEN_EXPIRED(1002001018, "访问令牌已过期"),
// OAUTH_INVALID_REFRESH_TOKEN_INVALID(1002001019, "刷新令牌已失效"),
// ========== 管理员模块 1002002000 ==========
ADMIN_NOT_FOUND(1002002000, "管理员不存在"),
// 废弃 ADMIN_USERNAME_NOT_REGISTERED(1002002000, "账号不存在"),
// 废弃 ADMIN_PASSWORD_ERROR(1002002001, "密码不正确"),
// ADMIN_IS_DISABLE(1002002002, "账号被禁用"),
// ADMIN_USERNAME_EXISTS(1002002002, "账号已经存在"),
// ADMIN_STATUS_EQUALS(1002002003, "账号已经是该状态"),
// ADMIN_DELETE_ONLY_DISABLE(1002002004, "只有关闭的账号才可以删除"),
// ADMIN_ADMIN_STATUS_CAN_NOT_UPDATE(1002002005, "管理员的账号状态不允许变更"),
// ADMIN_ASSIGN_ROLE_NOT_EXISTS(1002002006, "分配员工角色时,有角色不存在"),
// ADMIN_INVALID_PERMISSION(1002002007, "没有该操作权限"),
// ADMIN_ADMIN_CAN_NOT_UPDATE(1002002008, "管理员的账号不允许变更"),
// ADMIN_DEMO_CAN_NOT_WRITE(1002002009, "演示账号暂不允许写操作。欢迎加入我们的交流群http://t.cn/EKEr5WE"),
// ========== 资源模块 1002003000 ==========
// RESOURCE_NAME_DUPLICATE(1002003000, "已经存在该名字的资源"),
// RESOURCE_PARENT_NOT_EXISTS(1002003001, "父资源不存在"),
// RESOURCE_PARENT_ERROR(1002003002, "不能设置自己为父资源"),
// RESOURCE_NOT_EXISTS(1002003003, "资源不存在"),
// RESOURCE_EXISTS_CHILDREN(1002003004, "存在子资源,无法删除"),
// RESOURCE_PARENT_NOT_MENU(1002003005, "父资源的类型必须是菜单"),
// ========== 角色模块 1002004000 ==========
// ROLE_NOT_EXISTS(1002004000, "角色不存在"),
// ROLE_ASSIGN_RESOURCE_NOT_EXISTS(1002004001, "分配角色资源时,有资源不存在"),
// ========== 数据字典模块 1002005000 ==========
// DATA_DICT_EXISTS(1002005000, "该数据字典已经存在"),
// DATA_DICT_NOT_EXISTS(1002005001, "该数据字典不存在"),
// ========== 短信模板 1002006000 ==========
// SMS_PLATFORM_FAIL(1002006000, "短信平台调用失败【具体错误会动态替换】"),
// SMS_SIGN_NOT_EXISTENT(1002006001, "短信签名不存在"),
// SMS_SIGN_IS_EXISTENT(1002006002, "短信签名已存在"),
// SMS_TEMPLATE_NOT_EXISTENT(1002006020, "短信签名不存在"),
// SMS_TEMPLATE_IS_EXISTENT(1002006021, "短信签名不存在"),
// SMS_NOT_SEND_CLIENT(1002006030, "短信没有发送的client"),
// ========== 部门模块 1002007000 ==========
// DEPT_SAME_LEVEL_NAME_EXITS(1002007001,"当前级别部门名字已存在"),
// DEPT_PARENT_NOT_EXITS(1002007002,"父级部门不存在"),
// DEPT_NOT_EXITS(1002007003, "当前部门不存在"),
// DEPT_EXITS_CHILDREN(1002007004, "当前部门存在子部门"),
// DEPT_PARENT_NOT_LEGAL(1002007005, "父级部门不合法"),
;
private final int code;
private final String message;
SystemErrorCodeEnum(int code, String message) {
this.code = code;
this.message = message;
}
@Override
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
}

View File

@@ -0,0 +1,15 @@
package cn.iocoder.mall.system.biz.convert;
import cn.iocoder.mall.system.biz.bo.account.AccountBO;
import cn.iocoder.mall.system.biz.dataobject.account.AccountDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface AccountConvert {
AccountConvert INSTANCE = Mappers.getMapper(AccountConvert.class);
AccountBO convert(AccountDO accountDO);
}

View File

@@ -0,0 +1,15 @@
package cn.iocoder.mall.system.biz.convert;
import cn.iocoder.mall.system.biz.bo.admin.AdminBO;
import cn.iocoder.mall.system.biz.dataobject.admin.AdminDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface AdminConvert {
AdminConvert INSTANCE = Mappers.getMapper(AdminConvert.class);
AdminBO convert(AdminDO adminDO);
}

View File

@@ -0,0 +1,15 @@
package cn.iocoder.mall.system.biz.convert;
import cn.iocoder.mall.system.biz.bo.ouath2.OAuth2AccessTokenBO;
import cn.iocoder.mall.system.biz.dataobject.oauth2.OAuth2AccessTokenDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface OAuth2Convert {
OAuth2Convert INSTANCE = Mappers.getMapper(OAuth2Convert.class);
OAuth2AccessTokenBO convert(OAuth2AccessTokenDO accessTokenDO);
}

View File

@@ -0,0 +1,17 @@
package cn.iocoder.mall.system.biz.dao.account;
import cn.iocoder.mall.system.biz.dataobject.account.AccountDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface AccountMapper extends BaseMapper<AccountDO> {
default AccountDO selectByUsername(String username) {
return selectOne(new QueryWrapper<AccountDO>()
.eq("username", username)
);
}
}

View File

@@ -0,0 +1,10 @@
package cn.iocoder.mall.system.biz.dao.admin;
import cn.iocoder.mall.system.biz.dataobject.admin.AdminDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface AdminMapper extends BaseMapper<AdminDO> {
}

View File

@@ -0,0 +1,24 @@
package cn.iocoder.mall.system.biz.dao.oauth2;
import cn.iocoder.mall.system.biz.dataobject.oauth2.OAuth2AccessTokenDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface OAuth2AccessTokenMapper extends BaseMapper<OAuth2AccessTokenDO> {
default int updateToInvalid(Integer accountId) {
QueryWrapper<OAuth2AccessTokenDO> query = new QueryWrapper<OAuth2AccessTokenDO>()
.eq("account_id", accountId)
.eq("valid", true);
return update(new OAuth2AccessTokenDO().setValid(false), query);
}
default int updateToInvalidByRefreshToken(String refreshToken) {
QueryWrapper<OAuth2AccessTokenDO> query = new QueryWrapper<OAuth2AccessTokenDO>()
.eq("refresh_token", refreshToken).eq("valid", true);
return update(new OAuth2AccessTokenDO().setValid(false), query);
}
}

View File

@@ -0,0 +1,18 @@
package cn.iocoder.mall.system.biz.dao.oauth2;
import cn.iocoder.mall.system.biz.dataobject.oauth2.OAuth2RefreshTokenDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface OAuth2RefreshTokenMapper extends BaseMapper<OAuth2RefreshTokenDO> {
default int updateToInvalid(Integer accountId) {
QueryWrapper<OAuth2RefreshTokenDO> query = new QueryWrapper<OAuth2RefreshTokenDO>()
.eq("account_id", accountId)
.eq("valid", true);
return update(new OAuth2RefreshTokenDO().setValid(false), query);
}
}

View File

@@ -0,0 +1,66 @@
package cn.iocoder.mall.system.biz.dataobject.account;
import cn.iocoder.common.framework.dataobject.DeletableDO;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 账号实体
*/
@TableName(value = "account")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class AccountDO extends DeletableDO {
/**
* 账号编号
*/
private Integer id;
/**
* 登陆账号
*/
private String username;
/**
* 手机号
*/
private String mobile;
/**
* 邮箱
*/
private String email;
/**
* 密码
*
* // TODO 芋艿 暂时明文
*/
private String password;
/**
* 账号状态
*
* {@link cn.iocoder.common.framework.constant.CommonStatusEnum}
*/
private Integer status;
/**
* 创建 IP
*/
private String createIp;
/**
* 最后登陆时间
*/
private Date lastLoginTime;
/**
* 最后登陆 IP
*/
private String lastLoginIp;
/**
* 登陆次数
*/
private Integer loginTimes;
}

View File

@@ -0,0 +1,40 @@
package cn.iocoder.mall.system.biz.dataobject.admin;
import cn.iocoder.common.framework.dataobject.DeletableDO;
import cn.iocoder.mall.system.biz.dataobject.account.AccountDO;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 管理员实体
*/
@TableName(value = "admin")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class AdminDO extends DeletableDO {
/**
* 管理员编号
*/
private Integer id;
/**
* 账号编号
*
* 关联 {@link AccountDO#getId()}
*/
private Integer accountId;
/**
* 真实名字
*/
private String name;
/**
* 科室编号
*
* 关联 {@link DepartmentDO#getId()}
*/
private Integer departmentId;
}

View File

@@ -0,0 +1,35 @@
package cn.iocoder.mall.system.biz.dataobject.admin;
import cn.iocoder.common.framework.dataobject.DeletableDO;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 部门实体
*/
@TableName(value = "department")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class DepartmentDO extends DeletableDO {
/**
* 部门编号
*/
private Integer id;
/**
* 部门名称
*/
private String name;
/**
* 排序值
*/
private Integer sort;
/**
* 父级部门编号
*/
private Integer pid;
}

View File

@@ -0,0 +1,49 @@
package cn.iocoder.mall.system.biz.dataobject.oauth2;
import cn.iocoder.common.framework.dataobject.BaseDO;
import cn.iocoder.mall.system.biz.dataobject.account.AccountDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* OAuth2 访问令牌
*/
@TableName("oauth2_access_token")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class OAuth2AccessTokenDO extends BaseDO {
/**
* 访问令牌
*/
@TableId(type = IdType.INPUT)
private String id;
/**
* 刷新令牌
*
* 关联 {@link OAuth2RefreshTokenDO#getId()}
*/
private String refreshToken;
/**
* 账号编号
*
* 关联 {@link AccountDO#getId()}
*/
private Integer accountId;
/**
* 过期时间
*/
private Date expiresTime;
/**
* 是否有效
*/
private Boolean valid;
}

View File

@@ -0,0 +1,45 @@
package cn.iocoder.mall.system.biz.dataobject.oauth2;
import cn.iocoder.common.framework.dataobject.BaseDO;
import cn.iocoder.mall.system.biz.dataobject.account.AccountDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* OAuth2 刷新令牌
*
* idx_uid
*/
@TableName("oauth2_refresh_token")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class OAuth2RefreshTokenDO extends BaseDO {
/**
* 刷新令牌
*/
@TableId(type = IdType.INPUT)
private String id;
/**
* 账号编号
*
* 关联 {@link AccountDO#getId()}
*/
private Integer accountId;
/**
* 是否有效
*/
private Boolean valid;
/**
* 过期时间
*/
private Date expiresTime;
}

View File

@@ -0,0 +1,38 @@
package cn.iocoder.mall.system.biz.dataobject.user;
import cn.iocoder.common.framework.dataobject.DeletableDO;
import cn.iocoder.mall.system.biz.dataobject.account.AccountDO;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 用户实体
*/
@TableName(value = "user")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class UserDO extends DeletableDO {
/**
* 用户编号
*/
private Integer id;
/**
* 账号编号
*
* 关联 {@link AccountDO#getId()}
*/
private Integer accountId;
/**
* 昵称
*/
private String nickname;
/**
* 头像
*/
private String avatar;
}

View File

@@ -0,0 +1,14 @@
package cn.iocoder.mall.system.biz.dto.oatuh2;
import lombok.Data;
import lombok.experimental.Accessors;
// TODO 注释
@Data
@Accessors(chain = true)
public class OAuth2UsernameAuthenticateDTO {
private String username;
private String password;
}

View File

@@ -0,0 +1 @@
package cn.iocoder.mall.system.biz.dto;

View File

@@ -0,0 +1,14 @@
package cn.iocoder.mall.system.biz.service.account;
import cn.iocoder.mall.system.biz.bo.account.AccountBO;
/**
* 账号 Service 接口
*/
public interface AccountService {
AccountBO getByUsername(String username);
boolean matchPassword(String rawPassword, String encodedPassword);
}

View File

@@ -0,0 +1,30 @@
package cn.iocoder.mall.system.biz.service.account.impl;
import cn.iocoder.mall.system.biz.bo.account.AccountBO;
import cn.iocoder.mall.system.biz.convert.AccountConvert;
import cn.iocoder.mall.system.biz.dao.account.AccountMapper;
import cn.iocoder.mall.system.biz.dataobject.account.AccountDO;
import cn.iocoder.mall.system.biz.service.account.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Objects;
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountMapper accountMapper;
@Override
public AccountBO getByUsername(String username) {
AccountDO accountDO = accountMapper.selectByUsername(username);
return AccountConvert.INSTANCE.convert(accountDO);
}
@Override
public boolean matchPassword(String rawPassword, String encodedPassword) {
return Objects.equals(rawPassword, encodedPassword);
}
}

View File

@@ -0,0 +1,9 @@
package cn.iocoder.mall.system.biz.service.admin;
import cn.iocoder.mall.system.biz.bo.admin.AdminBO;
public interface AdminService {
AdminBO get(Integer id);
}

View File

@@ -0,0 +1,23 @@
package cn.iocoder.mall.system.biz.service.admin.impl;
import cn.iocoder.mall.system.biz.bo.admin.AdminBO;
import cn.iocoder.mall.system.biz.convert.AdminConvert;
import cn.iocoder.mall.system.biz.dao.admin.AdminMapper;
import cn.iocoder.mall.system.biz.dataobject.admin.AdminDO;
import cn.iocoder.mall.system.biz.service.admin.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class AdminServiceImpl implements AdminService {
@Autowired
private AdminMapper adminMapper;
@Override
public AdminBO get(Integer id) {
AdminDO adminDO = adminMapper.selectById(id);
return AdminConvert.INSTANCE.convert(adminDO);
}
}

View File

@@ -0,0 +1,13 @@
package cn.iocoder.mall.system.biz.service.oauth2;
import cn.iocoder.mall.system.biz.bo.ouath2.OAuth2AccessTokenBO;
import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2UsernameAuthenticateDTO;
/**
* OAuth2 Service 接口
*/
public interface OAuth2Service {
OAuth2AccessTokenBO authenticate(OAuth2UsernameAuthenticateDTO usernameAuthenticateDTO);
}

View File

@@ -0,0 +1,95 @@
package cn.iocoder.mall.system.biz.service.oauth2.impl;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.mall.system.biz.bo.account.AccountBO;
import cn.iocoder.mall.system.biz.bo.ouath2.OAuth2AccessTokenBO;
import cn.iocoder.mall.system.biz.convert.OAuth2Convert;
import cn.iocoder.mall.system.biz.dao.oauth2.OAuth2AccessTokenMapper;
import cn.iocoder.mall.system.biz.dao.oauth2.OAuth2RefreshTokenMapper;
import cn.iocoder.mall.system.biz.dataobject.oauth2.OAuth2AccessTokenDO;
import cn.iocoder.mall.system.biz.dataobject.oauth2.OAuth2RefreshTokenDO;
import cn.iocoder.mall.system.biz.dto.oatuh2.OAuth2UsernameAuthenticateDTO;
import cn.iocoder.mall.system.biz.service.account.AccountService;
import cn.iocoder.mall.system.biz.service.oauth2.OAuth2Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.UUID;
import static cn.iocoder.mall.system.biz.constant.SystemErrorCodeEnum.OAUTH2_ACCOUNT_NOT_FOUND;
import static cn.iocoder.mall.system.biz.constant.SystemErrorCodeEnum.OAUTH2_ACCOUNT_PASSWORD_ERROR;
@Service
public class OAuth2ServiceImpl implements OAuth2Service {
/**
* 访问令牌过期时间,单位:毫秒
*/
@Value("${modules.oauth2-code-service.access-token-expire-time-millis}")
private int accessTokenExpireTimeMillis;
/**
* 刷新令牌过期时间,单位:毫秒
*/
@Value("${modules.oauth2-code-service.refresh-token-expire-time-millis}")
private int refreshTokenExpireTimeMillis;
@Autowired
private AccountService accountService;
@Autowired
private OAuth2AccessTokenMapper oauth2AccessTokenMapper;
@Autowired
private OAuth2RefreshTokenMapper oauth2RefreshTokenMapper;
@Override
@Transactional
public OAuth2AccessTokenBO authenticate(OAuth2UsernameAuthenticateDTO usernameAuthenticateDTO) {
// 获得账号
AccountBO accountBO = accountService.getByUsername(usernameAuthenticateDTO.getUsername());
if (accountBO == null) {
throw ServiceExceptionUtil.exception(OAUTH2_ACCOUNT_NOT_FOUND);
}
// 校验密码
if (!accountService.matchPassword(usernameAuthenticateDTO.getPassword(), accountBO.getPassword())) {
throw ServiceExceptionUtil.exception(OAUTH2_ACCOUNT_PASSWORD_ERROR);
}
// 创建刷新令牌 + 访问令牌
OAuth2RefreshTokenDO oauth2RefreshTokenDO = createOAuth2RefreshToken(accountBO.getId());
OAuth2AccessTokenDO oauth2AccessTokenDO = createOAuth2AccessToken(accountBO.getId(), oauth2RefreshTokenDO.getId());
// 返回访问令牌
return OAuth2Convert.INSTANCE.convert(oauth2AccessTokenDO);
}
private OAuth2AccessTokenDO createOAuth2AccessToken(Integer accountId, String refreshToken) {
OAuth2AccessTokenDO accessToken = new OAuth2AccessTokenDO()
.setId(generateAccessToken())
.setAccountId(accountId)
.setRefreshToken(refreshToken)
.setExpiresTime(new Date(System.currentTimeMillis() + accessTokenExpireTimeMillis))
.setValid(true);
oauth2AccessTokenMapper.insert(accessToken);
return accessToken;
}
private OAuth2RefreshTokenDO createOAuth2RefreshToken(Integer accountId) {
OAuth2RefreshTokenDO refreshToken = new OAuth2RefreshTokenDO()
.setId(generateRefreshToken())
.setAccountId(accountId)
.setExpiresTime(new Date(System.currentTimeMillis() + refreshTokenExpireTimeMillis))
.setValid(true);
oauth2RefreshTokenMapper.insert(refreshToken);
return refreshToken;
}
private String generateAccessToken() {
return UUID.randomUUID().toString().replaceAll("-", "");
}
private String generateRefreshToken() {
return UUID.randomUUID().toString().replaceAll("-", "");
}
}

View File

@@ -0,0 +1,4 @@
##################### 业务模块 #####################
## OAuth2CodeService
modules.oauth2-code-service.access-token-expire-time-millis = 2880000
modules.oauth2-code-service.refresh-token-expire-time-millis = 43200000

View File

@@ -0,0 +1,20 @@
spring:
# 数据源配置项
datasource:
url: jdbc:mysql://s1.iocoder.cn:3306/mall_system?useSSL=false&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
username: root
password: ${MALL_MYSQL_PASSWORD}
# MyBatis Plus 配置项
mybatis-plus:
configuration:
map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
global-config:
db-config:
id-type: auto
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
mapper-locations: classpath*:mapper/*.xml
type-aliases-package: cn.iocoder.mall.system.biz.dataobject