From 8aa45406fdaaaf4b8c1604d31b65c020d8ff8a0d Mon Sep 17 00:00:00 2001 From: timfruit Date: Sun, 31 Oct 2021 13:09:55 +0800 Subject: [PATCH 01/41] =?UTF-8?q?=E6=8B=93=E5=B1=95=E6=8E=88=E6=9D=83?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E6=8A=BD=E5=8F=96=E6=88=90=E5=8D=95=E7=8B=AC?= =?UTF-8?q?=E7=9A=84starter,=E6=8B=93=E5=B1=95=E9=85=8D=E7=BD=AE=E5=92=8C?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E9=85=8D=E7=BD=AE=E9=BD=90=E5=B9=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/auth/SysAuthController.java | 4 +- .../user/SysUserProfileController.java | 4 +- .../service/auth/impl/SysAuthServiceImpl.java | 17 ++- .../service/auth/SysAuthServiceImplTest.java | 4 +- yudao-core-service/pom.xml | 10 +- ...pper.java => SysSocialUserCoreMapper.java} | 3 +- .../social/SysSocialAuthUserRedisDAO.java | 3 +- ...Service.java => SysSocialCoreService.java} | 10 +- ...mpl.java => SysSocialCoreServiceImpl.java} | 16 +-- .../social/SysSocialCoreServiceTest.java | 19 ++- yudao-dependencies/pom.xml | 6 + yudao-framework/pom.xml | 1 + .../pom.xml | 50 ++++++++ .../config/YudaoSocialAutoConfiguration.java | 29 +++++ .../social/core/YudaoAuthRequestFactory.java | 108 ++++++++++++++++++ .../social/core/enums}/AuthExtendSource.java | 2 +- .../social/core/model}/AuthExtendToken.java | 5 +- .../AuthWeChatMiniProgramRequest.java | 34 +++--- .../main/resources/META-INF/spring.factories | 2 + .../controller/auth/SysAuthController.java | 4 +- .../service/auth/impl/SysAuthServiceImpl.java | 16 +-- .../src/main/resources/application-dev.yaml | 22 ++-- .../src/main/resources/application-local.yaml | 18 ++- 23 files changed, 288 insertions(+), 99 deletions(-) rename yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/dal/mysql/social/{SysSocialUserMapper.java => SysSocialUserCoreMapper.java} (89%) rename yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/service/social/{SysSocialService.java => SysSocialCoreService.java} (91%) rename yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/service/social/impl/{SysSocialServiceImpl.java => SysSocialCoreServiceImpl.java} (93%) rename yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/social/SysSocialServiceTest.java => yudao-core-service/src/test/java/cn/iocoder/yudao/coreservice/modules/system/service/social/SysSocialCoreServiceTest.java (92%) create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-social/pom.xml create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/config/YudaoSocialAutoConfiguration.java create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java rename {yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/compent/justauth => yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/enums}/AuthExtendSource.java (91%) rename {yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/compent/justauth => yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/model}/AuthExtendToken.java (71%) rename {yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/compent/justauth => yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/request}/AuthWeChatMiniProgramRequest.java (67%) create mode 100644 yudao-framework/yudao-spring-boot-starter-biz-social/src/main/resources/META-INF/spring.factories diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/auth/SysAuthController.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/auth/SysAuthController.java index 16130e17e..c557b789a 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/auth/SysAuthController.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/auth/SysAuthController.java @@ -9,7 +9,7 @@ import cn.iocoder.yudao.adminserver.modules.system.service.auth.SysAuthService; import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysPermissionService; import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysRoleService; import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO; -import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialService; +import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialCoreService; import cn.iocoder.yudao.coreservice.modules.system.service.user.SysUserCoreService; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; @@ -50,7 +50,7 @@ public class SysAuthController { @Resource private SysPermissionService permissionService; @Resource - private SysSocialService socialService; + private SysSocialCoreService socialService; @PostMapping("/login") @ApiOperation("使用账号密码登录") diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/user/SysUserProfileController.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/user/SysUserProfileController.java index 48236a7ab..0b85016c1 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/user/SysUserProfileController.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/user/SysUserProfileController.java @@ -15,7 +15,7 @@ import cn.iocoder.yudao.adminserver.modules.system.service.permission.SysRoleSer import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.social.SysSocialUserDO; import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO; -import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialService; +import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialCoreService; import cn.iocoder.yudao.coreservice.modules.system.service.user.SysUserCoreService; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; @@ -56,7 +56,7 @@ public class SysUserProfileController { @Resource private SysRoleService roleService; @Resource - private SysSocialService socialService; + private SysSocialCoreService socialService; @GetMapping("/get") @ApiOperation("获得登录用户信息") diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java index 558967c2e..abb6a3dca 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java @@ -17,7 +17,7 @@ import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO import cn.iocoder.yudao.coreservice.modules.system.service.auth.SysUserSessionCoreService; import cn.iocoder.yudao.coreservice.modules.system.service.logger.SysLoginLogCoreService; import cn.iocoder.yudao.coreservice.modules.system.service.logger.dto.SysLoginLogCreateReqDTO; -import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialService; +import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialCoreService; import cn.iocoder.yudao.coreservice.modules.system.service.user.SysUserCoreService; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; @@ -73,10 +73,9 @@ public class SysAuthServiceImpl implements SysAuthService { @Resource private SysUserSessionCoreService userSessionCoreService; @Resource - private SysSocialService socialService; + private SysSocialCoreService socialService; - // TODO @timfruit:静态枚举类,需要都大写,例如说 USER_TYPE_ENUM;静态变量,放在普通变量前面;这个实践不错哈。 - private static final UserTypeEnum userTypeEnum = UserTypeEnum.ADMIN; + private static final UserTypeEnum USER_TYPE_ENUM = UserTypeEnum.ADMIN; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { @@ -201,7 +200,7 @@ public class SysAuthServiceImpl implements SysAuthService { // 如果未绑定 SysSocialUserDO 用户,则无法自动登录,进行报错 String unionId = socialService.getAuthUserUnionId(authUser); - List socialUsers = socialService.getAllSocialUserList(reqVO.getType(), unionId, userTypeEnum); + List socialUsers = socialService.getAllSocialUserList(reqVO.getType(), unionId, USER_TYPE_ENUM); if (CollUtil.isEmpty(socialUsers)) { throw exception(AUTH_THIRD_LOGIN_NOT_BIND); } @@ -218,7 +217,7 @@ public class SysAuthServiceImpl implements SysAuthService { loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId())); // 获取用户角色列表 // 绑定社交用户(更新) - socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, userTypeEnum); + socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, USER_TYPE_ENUM); // 缓存登录用户到 Redis 中,返回 sessionId 编号 return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); @@ -235,7 +234,7 @@ public class SysAuthServiceImpl implements SysAuthService { loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId())); // 获取用户角色列表 // 绑定社交用户(新增) - socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, userTypeEnum); + socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, USER_TYPE_ENUM); // 缓存登录用户到 Redis 中,返回 sessionId 编号 return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); @@ -248,7 +247,7 @@ public class SysAuthServiceImpl implements SysAuthService { Assert.notNull(authUser, "授权用户不为空"); // 绑定社交用户(新增) - socialService.bindSocialUser(userId, reqVO.getType(), authUser, userTypeEnum); + socialService.bindSocialUser(userId, reqVO.getType(), authUser, USER_TYPE_ENUM); } @Override @@ -269,7 +268,7 @@ public class SysAuthServiceImpl implements SysAuthService { reqDTO.setLogType(SysLoginLogTypeEnum.LOGOUT_SELF.getType()); reqDTO.setTraceId(TracerUtils.getTraceId()); reqDTO.setUserId(userId); - reqDTO.setUserType(userTypeEnum.getValue()); + reqDTO.setUserType(USER_TYPE_ENUM.getValue()); reqDTO.setUsername(username); reqDTO.setUserAgent(ServletUtils.getUserAgent()); reqDTO.setUserIp(ServletUtils.getClientIP()); diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/SysAuthServiceImplTest.java b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/SysAuthServiceImplTest.java index c09a194aa..d8fbec5b2 100644 --- a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/SysAuthServiceImplTest.java +++ b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/SysAuthServiceImplTest.java @@ -11,7 +11,7 @@ import cn.iocoder.yudao.adminserver.modules.system.service.user.SysUserService; import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user.SysUserDO; import cn.iocoder.yudao.coreservice.modules.system.service.auth.SysUserSessionCoreService; import cn.iocoder.yudao.coreservice.modules.system.service.logger.SysLoginLogCoreService; -import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialService; +import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialCoreService; import cn.iocoder.yudao.coreservice.modules.system.service.user.SysUserCoreService; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.security.core.LoginUser; @@ -66,7 +66,7 @@ public class SysAuthServiceImplTest extends BaseDbUnitTest { @MockBean private SysUserSessionCoreService userSessionCoreService; @MockBean - private SysSocialService socialService; + private SysSocialCoreService socialService; @Test public void testLoadUserByUsername_success() { diff --git a/yudao-core-service/pom.xml b/yudao-core-service/pom.xml index 4fd85c0aa..c4e79d7a3 100644 --- a/yudao-core-service/pom.xml +++ b/yudao-core-service/pom.xml @@ -36,6 +36,10 @@ cn.iocoder.boot yudao-spring-boot-starter-biz-pay + + cn.iocoder.boot + yudao-spring-boot-starter-biz-social + @@ -96,12 +100,6 @@ guava - - - com.xkcoding.justauth - justauth-spring-boot-starter - - diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/dal/mysql/social/SysSocialUserMapper.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/dal/mysql/social/SysSocialUserCoreMapper.java similarity index 89% rename from yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/dal/mysql/social/SysSocialUserMapper.java rename to yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/dal/mysql/social/SysSocialUserCoreMapper.java index ee8db4eac..727c38e67 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/dal/mysql/social/SysSocialUserMapper.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/dal/mysql/social/SysSocialUserCoreMapper.java @@ -8,9 +8,8 @@ import org.apache.ibatis.annotations.Mapper; import java.util.Collection; import java.util.List; -// TODO @timfruit:SysSocialUserCoreMapper 改名,方便区分 @Mapper -public interface SysSocialUserMapper extends BaseMapperX { +public interface SysSocialUserCoreMapper extends BaseMapperX { default List selectListByTypeAndUnionId(Integer userType, Collection types, String unionId) { return selectList(new QueryWrapper().eq("user_type", userType) diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/dal/redis/social/SysSocialAuthUserRedisDAO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/dal/redis/social/SysSocialAuthUserRedisDAO.java index 514281071..0c033f89e 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/dal/redis/social/SysSocialAuthUserRedisDAO.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/dal/redis/social/SysSocialAuthUserRedisDAO.java @@ -10,9 +10,8 @@ import javax.annotation.Resource; import static cn.iocoder.yudao.coreservice.modules.system.dal.redis.SysRedisKeyCoreConstants.SOCIAL_AUTH_USER; -// TODO @timfruit,这里的 AuthUser 还是保留全路径,主要想体现出来,不是自己定义的 /** - * 社交 {@link AuthUser} 的 RedisDAO + * 社交 {@link me.zhyd.oauth.model.AuthUser} 的 RedisDAO * * @author 芋道源码 */ diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/service/social/SysSocialService.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/service/social/SysSocialCoreService.java similarity index 91% rename from yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/service/social/SysSocialService.java rename to yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/service/social/SysSocialCoreService.java index 8a8df27d6..17634b320 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/service/social/SysSocialService.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/service/social/SysSocialCoreService.java @@ -15,8 +15,7 @@ import java.util.List; * * @author 芋道源码 */ -// TODO @timfruit:SysSocialCoreService 改名,方便区分 -public interface SysSocialService { +public interface SysSocialCoreService { /** * 获得社交平台的授权 URL @@ -50,6 +49,7 @@ public interface SysSocialService { * @param type 社交平台的类型 {@link SysSocialTypeEnum} * @param unionId 社交平台的 unionId * @return 社交用户列表 + * @param userTypeEnum 全局用户类型 */ List getAllSocialUserList(Integer type, String unionId, UserTypeEnum userTypeEnum); @@ -58,6 +58,7 @@ public interface SysSocialService { * * @param userId 用户编号 * @return 社交用户列表 + * @param userTypeEnum 全局用户类型 */ List getSocialUserList(Long userId, UserTypeEnum userTypeEnum); @@ -67,6 +68,7 @@ public interface SysSocialService { * @param userId 用户编号 * @param type 社交平台的类型 {@link SysSocialTypeEnum} * @param authUser 授权用户 + * @param userTypeEnum 全局用户类型 */ void bindSocialUser(Long userId, Integer type, AuthUser authUser, UserTypeEnum userTypeEnum); @@ -76,8 +78,8 @@ public interface SysSocialService { * @param userId 用户编号 * @param type 社交平台的类型 {@link SysSocialTypeEnum} * @param unionId 社交平台的 unionId + * @param userTypeEnum 全局用户类型 */ - void unbindSocialUser(Long userId, Integer type, String unionId,UserTypeEnum userTypeEnum); - // TODO @timfruit:逗号后面要有空格;缺少了 @userTypeEnum 的注释,都补充下哈。 + void unbindSocialUser(Long userId, Integer type, String unionId, UserTypeEnum userTypeEnum); } diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/service/social/impl/SysSocialServiceImpl.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/service/social/impl/SysSocialCoreServiceImpl.java similarity index 93% rename from yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/service/social/impl/SysSocialServiceImpl.java rename to yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/service/social/impl/SysSocialCoreServiceImpl.java index bde40c3c4..0c3bcca9a 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/service/social/impl/SysSocialServiceImpl.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/service/social/impl/SysSocialCoreServiceImpl.java @@ -2,15 +2,15 @@ package cn.iocoder.yudao.coreservice.modules.system.service.social.impl; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.social.SysSocialUserDO; -import cn.iocoder.yudao.coreservice.modules.system.dal.mysql.social.SysSocialUserMapper; +import cn.iocoder.yudao.coreservice.modules.system.dal.mysql.social.SysSocialUserCoreMapper; import cn.iocoder.yudao.coreservice.modules.system.dal.redis.social.SysSocialAuthUserRedisDAO; import cn.iocoder.yudao.coreservice.modules.system.enums.social.SysSocialTypeEnum; -import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialService; +import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialCoreService; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.http.HttpUtils; +import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory; import com.google.common.annotations.VisibleForTesting; -import com.xkcoding.justauth.AuthRequestFactory; import lombok.extern.slf4j.Slf4j; import me.zhyd.oauth.model.AuthCallback; import me.zhyd.oauth.model.AuthResponse; @@ -38,21 +38,21 @@ import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString @Service @Validated @Slf4j -public class SysSocialServiceImpl implements SysSocialService { +public class SysSocialCoreServiceImpl implements SysSocialCoreService { @Resource - private AuthRequestFactory authRequestFactory; + private YudaoAuthRequestFactory yudaoAuthRequestFactory; @Resource private SysSocialAuthUserRedisDAO authSocialUserRedisDAO; @Resource - private SysSocialUserMapper socialUserMapper; + private SysSocialUserCoreMapper socialUserMapper; @Override public String getAuthorizeUrl(Integer type, String redirectUri) { // 获得对应的 AuthRequest 实现 - AuthRequest authRequest = authRequestFactory.get(SysSocialTypeEnum.valueOfType(type).getSource()); + AuthRequest authRequest = yudaoAuthRequestFactory.get(SysSocialTypeEnum.valueOfType(type).getSource()); // 生成跳转地址 String authorizeUri = authRequest.authorize(AuthStateUtils.createState()); return HttpUtils.replaceUrlQuery(authorizeUri, "redirect_uri", redirectUri); @@ -161,7 +161,7 @@ public class SysSocialServiceImpl implements SysSocialService { * @return 授权的用户 */ private AuthUser getAuthUser0(Integer type, AuthCallback authCallback) { - AuthRequest authRequest = authRequestFactory.get(SysSocialTypeEnum.valueOfType(type).getSource()); + AuthRequest authRequest = yudaoAuthRequestFactory.get(SysSocialTypeEnum.valueOfType(type).getSource()); AuthResponse authResponse = authRequest.login(authCallback); log.info("[getAuthUser0][请求社交平台 type({}) request({}) response({})]", type, toJsonString(authCallback), toJsonString(authResponse)); diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/social/SysSocialServiceTest.java b/yudao-core-service/src/test/java/cn/iocoder/yudao/coreservice/modules/system/service/social/SysSocialCoreServiceTest.java similarity index 92% rename from yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/social/SysSocialServiceTest.java rename to yudao-core-service/src/test/java/cn/iocoder/yudao/coreservice/modules/system/service/social/SysSocialCoreServiceTest.java index cec84c1ed..2a33dd869 100644 --- a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/social/SysSocialServiceTest.java +++ b/yudao-core-service/src/test/java/cn/iocoder/yudao/coreservice/modules/system/service/social/SysSocialCoreServiceTest.java @@ -1,11 +1,11 @@ -package cn.iocoder.yudao.adminserver.modules.system.service.social; +package cn.iocoder.yudao.coreservice.modules.system.service.social; -import cn.iocoder.yudao.adminserver.BaseDbAndRedisUnitTest; +import cn.iocoder.yudao.coreservice.BaseDbAndRedisUnitTest; import cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.social.SysSocialUserDO; -import cn.iocoder.yudao.coreservice.modules.system.dal.mysql.social.SysSocialUserMapper; +import cn.iocoder.yudao.coreservice.modules.system.dal.mysql.social.SysSocialUserCoreMapper; import cn.iocoder.yudao.coreservice.modules.system.dal.redis.social.SysSocialAuthUserRedisDAO; import cn.iocoder.yudao.coreservice.modules.system.enums.social.SysSocialTypeEnum; -import cn.iocoder.yudao.coreservice.modules.system.service.social.impl.SysSocialServiceImpl; +import cn.iocoder.yudao.coreservice.modules.system.service.social.impl.SysSocialCoreServiceImpl; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import com.xkcoding.justauth.AuthRequestFactory; import me.zhyd.oauth.model.AuthUser; @@ -23,20 +23,19 @@ import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; import static org.junit.jupiter.api.Assertions.assertEquals; -// TODO @timfruit:这个单元测试,挪到 yudao-core-service /** - * {@link SysSocialServiceImpl} 的单元测试类 + * {@link SysSocialCoreServiceImpl} 的单元测试类 * * @author 芋道源码 */ -@Import({SysSocialServiceImpl.class, SysSocialAuthUserRedisDAO.class}) -public class SysSocialServiceTest extends BaseDbAndRedisUnitTest { +@Import({SysSocialCoreServiceImpl.class, SysSocialAuthUserRedisDAO.class}) +public class SysSocialCoreServiceTest extends BaseDbAndRedisUnitTest { @Resource - private SysSocialServiceImpl socialService; + private SysSocialCoreServiceImpl socialService; @Resource - private SysSocialUserMapper socialUserMapper; + private SysSocialUserCoreMapper socialUserMapper; @MockBean private AuthRequestFactory authRequestFactory; diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index fba394150..b5028e909 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -350,6 +350,12 @@ ${revision} + + cn.iocoder.boot + yudao-spring-boot-starter-biz-social + ${revision} + + org.projectlombok lombok diff --git a/yudao-framework/pom.xml b/yudao-framework/pom.xml index f3927b3a3..21eb1eabe 100644 --- a/yudao-framework/pom.xml +++ b/yudao-framework/pom.xml @@ -31,6 +31,7 @@ yudao-spring-boot-starter-biz-pay yudao-spring-boot-starter-biz-weixin yudao-spring-boot-starter-extension + yudao-spring-boot-starter-biz-social yudao-framework diff --git a/yudao-framework/yudao-spring-boot-starter-biz-social/pom.xml b/yudao-framework/yudao-spring-boot-starter-biz-social/pom.xml new file mode 100644 index 000000000..7588af0c3 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-social/pom.xml @@ -0,0 +1,50 @@ + + + + cn.iocoder.boot + yudao-framework + ${revision} + + jar + 4.0.0 + + yudao-spring-boot-starter-biz-social + ${artifactId} + + + + cn.iocoder.boot + yudao-common + + + + org.springframework.boot + spring-boot-starter-aop + + + + cn.iocoder.boot + yudao-spring-boot-starter-web + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + com.xkcoding.justauth + justauth-spring-boot-starter + + + cn.iocoder.boot + yudao-spring-boot-starter-redis + + + + + + \ No newline at end of file diff --git a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/config/YudaoSocialAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/config/YudaoSocialAutoConfiguration.java new file mode 100644 index 000000000..a6c468af5 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/config/YudaoSocialAutoConfiguration.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.framework.social.config; + +import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory; +import com.xkcoding.justauth.autoconfigure.JustAuthProperties; +import lombok.extern.slf4j.Slf4j; +import me.zhyd.oauth.cache.AuthStateCache; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 社交自动装配类 + * + * @author timfruit + * @date 2021-10-30 + */ +@Slf4j +@Configuration +@EnableConfigurationProperties(JustAuthProperties.class) +public class YudaoSocialAutoConfiguration { + + @Bean + @ConditionalOnProperty(prefix = "justauth", value = "enabled", havingValue = "true", matchIfMissing = true) + public YudaoAuthRequestFactory yudaoAuthRequestFactory(JustAuthProperties properties, AuthStateCache authStateCache) { + return new YudaoAuthRequestFactory(properties, authStateCache); + } + +} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java new file mode 100644 index 000000000..998c70a12 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java @@ -0,0 +1,108 @@ +package cn.iocoder.yudao.framework.social.core; + +import cn.hutool.core.util.EnumUtil; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.social.core.enums.AuthExtendSource; +import cn.iocoder.yudao.framework.social.core.request.AuthWeChatMiniProgramRequest; +import com.xkcoding.http.config.HttpConfig; +import com.xkcoding.justauth.AuthRequestFactory; +import com.xkcoding.justauth.autoconfigure.JustAuthProperties; +import me.zhyd.oauth.cache.AuthStateCache; +import me.zhyd.oauth.config.AuthConfig; +import me.zhyd.oauth.config.AuthSource; +import me.zhyd.oauth.request.AuthRequest; +import org.springframework.util.CollectionUtils; + +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.util.Map; + +/** + * 第三方授权拓展request工厂类 + * + * @author timfruit + * @date 2021-10-31 + */ +public class YudaoAuthRequestFactory extends AuthRequestFactory { + protected JustAuthProperties properties; + protected AuthStateCache authStateCache; + + public YudaoAuthRequestFactory(JustAuthProperties properties, AuthStateCache authStateCache) { + super(properties, authStateCache); + this.properties = properties; + this.authStateCache = authStateCache; + } + + /** + * 返回AuthRequest对象 + * + * @param source {@link AuthSource} + * @return {@link AuthRequest} + */ + public AuthRequest get(String source) { + //先尝试获取自定义扩展的 + AuthRequest authRequest = getExtendRequest(source); + + if (authRequest == null) { + authRequest = super.get(source); + } + + return authRequest; + } + + + protected AuthRequest getExtendRequest(String source) { + AuthExtendSource authExtendSource; + + try { + authExtendSource = EnumUtil.fromString(AuthExtendSource.class, source.toUpperCase()); + } catch (IllegalArgumentException e) { + // 无自定义匹配 + return null; + } + + // 拓展配置和默认配置齐平,properties放在一起 + AuthConfig config = properties.getType().get(authExtendSource.name()); + // 找不到对应关系,直接返回空 + if (config == null) { + return null; + } + + // 配置 http config + configureHttpConfig(authExtendSource.name(), config, properties.getHttpConfig()); + + switch (authExtendSource) { + case WECHAT_MINI_PROGRAM: + return new AuthWeChatMiniProgramRequest(config, authStateCache); + default: + return null; + } + } + + /** + * 配置 http 相关的配置 + * + * @param authSource {@link AuthSource} + * @param authConfig {@link AuthConfig} + */ + protected void configureHttpConfig(String authSource, AuthConfig authConfig, JustAuthProperties.JustAuthHttpConfig httpConfig) { + if (null == httpConfig) { + return; + } + Map proxyConfigMap = httpConfig.getProxy(); + if (CollectionUtils.isEmpty(proxyConfigMap)) { + return; + } + JustAuthProperties.JustAuthProxyConfig proxyConfig = proxyConfigMap.get(authSource); + + if (null == proxyConfig) { + return; + } + + authConfig.setHttpConfig(HttpConfig.builder() + .timeout(httpConfig.getTimeout()) + .proxy(new Proxy(Proxy.Type.valueOf(proxyConfig.getType()), new InetSocketAddress(proxyConfig.getHostname(), proxyConfig.getPort()))) + .build()); + } + +} diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/compent/justauth/AuthExtendSource.java b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/enums/AuthExtendSource.java similarity index 91% rename from yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/compent/justauth/AuthExtendSource.java rename to yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/enums/AuthExtendSource.java index e005114ac..bd19b8d06 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/compent/justauth/AuthExtendSource.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/enums/AuthExtendSource.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.coreservice.modules.system.compent.justauth; +package cn.iocoder.yudao.framework.social.core.enums; import me.zhyd.oauth.config.AuthSource; diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/compent/justauth/AuthExtendToken.java b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/model/AuthExtendToken.java similarity index 71% rename from yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/compent/justauth/AuthExtendToken.java rename to yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/model/AuthExtendToken.java index 2ecb0d461..3397a4976 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/compent/justauth/AuthExtendToken.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/model/AuthExtendToken.java @@ -1,10 +1,11 @@ -package cn.iocoder.yudao.coreservice.modules.system.compent.justauth; +package cn.iocoder.yudao.framework.social.core.model; import lombok.*; import me.zhyd.oauth.model.AuthToken; /** - * TODO @timfruit:类注释 + * 授权所需的token 拓展类 + * * @author timfruit * @date 2021-10-29 */ diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/compent/justauth/AuthWeChatMiniProgramRequest.java b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/request/AuthWeChatMiniProgramRequest.java similarity index 67% rename from yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/compent/justauth/AuthWeChatMiniProgramRequest.java rename to yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/request/AuthWeChatMiniProgramRequest.java index 664f9157f..a875c3b6e 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/compent/justauth/AuthWeChatMiniProgramRequest.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/request/AuthWeChatMiniProgramRequest.java @@ -1,6 +1,9 @@ -package cn.iocoder.yudao.coreservice.modules.system.compent.justauth; +package cn.iocoder.yudao.framework.social.core.request; -import com.alibaba.fastjson.JSONObject; +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import cn.iocoder.yudao.framework.social.core.enums.AuthExtendSource; +import cn.iocoder.yudao.framework.social.core.model.AuthExtendToken; +import lombok.Data; import me.zhyd.oauth.cache.AuthStateCache; import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.exception.AuthException; @@ -11,9 +14,6 @@ import me.zhyd.oauth.request.AuthDefaultRequest; import me.zhyd.oauth.utils.HttpUtils; import me.zhyd.oauth.utils.UrlBuilder; -// TODO @timfruit:新建一个 yudao-spring-boot-starter-biz-social 包,把这个拓展拿进去哈。另外,可以思考下。 -// 1. application-local.yaml 的配置里,justauth.extend.enum-class 能否不配置,而是自动配置好 -// 2. application-local.yaml 的配置里,justauth.extend.extend.config.WECHAT_MINI_PROGRAM 有办法和 justauth.type.WECHAT_MP 持平 /** * 微信小程序登陆 * @@ -34,14 +34,14 @@ public class AuthWeChatMiniProgramRequest extends AuthDefaultRequest { protected AuthToken getAccessToken(AuthCallback authCallback) { // https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html String response = new HttpUtils(config.getHttpConfig()).get(accessTokenUrl(authCallback.getCode())); - JSONObject accessTokenObject = JSONObject.parseObject(response); // TODO @timfruit:使用 JsonUtils,项目尽量避免直接使用某个 json 库 + CodeSessionResponse accessTokenObject = JsonUtils.parseObject(response, CodeSessionResponse.class); this.checkResponse(accessTokenObject); AuthExtendToken token = new AuthExtendToken(); - token.setMiniSessionKey(accessTokenObject.getString("session_key")); - token.setOpenId(accessTokenObject.getString("openid")); - token.setUnionId(accessTokenObject.getString("unionid")); + token.setMiniSessionKey(accessTokenObject.session_key); + token.setOpenId(accessTokenObject.openid); + token.setUnionId(accessTokenObject.unionid); return token; } @@ -64,10 +64,9 @@ public class AuthWeChatMiniProgramRequest extends AuthDefaultRequest { * * @param object 请求响应内容 */ - private void checkResponse(JSONObject object) { - int code = object.getIntValue("errcode"); - if(code != 0){ // TODO @timfruit:if (code != 0) { ,注意空格 - throw new AuthException(object.getIntValue("errcode"), object.getString("errmsg")); + private void checkResponse(CodeSessionResponse object) { + if (object.errcode != 0) { + throw new AuthException(object.errcode, object.errmsg); } } @@ -87,4 +86,13 @@ public class AuthWeChatMiniProgramRequest extends AuthDefaultRequest { .build(); } + @Data + private static class CodeSessionResponse { + private int errcode; + private String errmsg; + private String session_key; + private String openid; + private String unionid; + } + } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/resources/META-INF/spring.factories b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000..dcd4dcf71 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + cn.iocoder.yudao.framework.social.config.YudaoSocialAutoConfiguration diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.java index 6d18d53be..fbca500f7 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/controller/auth/SysAuthController.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.userserver.modules.system.controller.auth; -import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialService; +import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialCoreService; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.userserver.modules.system.controller.auth.vo.*; @@ -36,7 +36,7 @@ public class SysAuthController { @Resource private SysSmsCodeService smsCodeService; @Resource - private SysSocialService socialService; + private SysSocialCoreService socialService; @PostMapping("/login") diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java index 2394cd03a..e4b938861 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java @@ -9,7 +9,7 @@ import cn.iocoder.yudao.coreservice.modules.system.enums.logger.SysLoginResultEn import cn.iocoder.yudao.coreservice.modules.system.service.auth.SysUserSessionCoreService; import cn.iocoder.yudao.coreservice.modules.system.service.logger.SysLoginLogCoreService; import cn.iocoder.yudao.coreservice.modules.system.service.logger.dto.SysLoginLogCreateReqDTO; -import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialService; +import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialCoreService; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; @@ -64,8 +64,8 @@ public class SysAuthServiceImpl implements SysAuthService { @Resource private SysUserSessionCoreService userSessionCoreService; @Resource - private SysSocialService socialService; - private static final UserTypeEnum userTypeEnum = UserTypeEnum.MEMBER; + private SysSocialCoreService socialService; + private static final UserTypeEnum USER_TYPE_ENUM = UserTypeEnum.MEMBER; @Override public UserDetails loadUserByUsername(String mobile) throws UsernameNotFoundException { @@ -114,7 +114,7 @@ public class SysAuthServiceImpl implements SysAuthService { // 如果未绑定 SysSocialUserDO 用户,则无法自动登录,进行报错 String unionId = socialService.getAuthUserUnionId(authUser); - List socialUsers = socialService.getAllSocialUserList(reqVO.getType(), unionId, userTypeEnum); + List socialUsers = socialService.getAllSocialUserList(reqVO.getType(), unionId, USER_TYPE_ENUM); if (CollUtil.isEmpty(socialUsers)) { throw exception(AUTH_THIRD_LOGIN_NOT_BIND); } @@ -130,7 +130,7 @@ public class SysAuthServiceImpl implements SysAuthService { LoginUser loginUser = SysAuthConvert.INSTANCE.convert(user); // 绑定社交用户(更新) - socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, userTypeEnum); + socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, USER_TYPE_ENUM); // 缓存登录用户到 Redis 中,返回 sessionId 编号 return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); @@ -147,7 +147,7 @@ public class SysAuthServiceImpl implements SysAuthService { // loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId())); // 获取用户角色列表 // 绑定社交用户(新增) - socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, userTypeEnum); + socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, USER_TYPE_ENUM); // 缓存登录用户到 Redis 中,返回 sessionId 编号 return userSessionCoreService.createUserSession(loginUser, userIp, userAgent); @@ -160,7 +160,7 @@ public class SysAuthServiceImpl implements SysAuthService { org.springframework.util.Assert.notNull(authUser, "授权用户不为空"); // 绑定社交用户(新增) - socialService.bindSocialUser(userId, reqVO.getType(), authUser, userTypeEnum); + socialService.bindSocialUser(userId, reqVO.getType(), authUser, USER_TYPE_ENUM); } private LoginUser login0(String username, String password) { @@ -271,7 +271,7 @@ public class SysAuthServiceImpl implements SysAuthService { reqDTO.setLogType(SysLoginLogTypeEnum.LOGOUT_SELF.getType()); reqDTO.setTraceId(TracerUtils.getTraceId()); reqDTO.setUserId(userId); - reqDTO.setUserType(userTypeEnum.getValue()); + reqDTO.setUserType(USER_TYPE_ENUM.getValue()); reqDTO.setUsername(username); reqDTO.setUserAgent(ServletUtils.getUserAgent()); reqDTO.setUserIp(ServletUtils.getClientIP()); diff --git a/yudao-user-server/src/main/resources/application-dev.yaml b/yudao-user-server/src/main/resources/application-dev.yaml index 858e97739..20e0056b1 100644 --- a/yudao-user-server/src/main/resources/application-dev.yaml +++ b/yudao-user-server/src/main/resources/application-dev.yaml @@ -145,24 +145,16 @@ yudao: justauth: enabled: true - type: # TODO @timfruit:GITEE、DINGTALK、WECHAT_ENTERPRISE 这个几个,对于用户端是不需要的哈,可以删除噢 - GITEE: # Gitee - client-id: ee61f0374a4c6c404a8717094caa7a410d76950e45ff60348015830c519ba5c1 - client-secret: 7c044a5671be3b051414db0cf2cec6ad702dd298d2416ba24ceaf608e6fa26f9 - ignore-check-redirect-uri: true - DINGTALK: # 钉钉 - client-id: dingvrnreaje3yqvzhxg - client-secret: i8E6iZyDvZj51JIb0tYsYfVQYOks9Cq1lgryEjFRqC79P3iJcrxEwT6Qk2QvLrLI - ignore-check-redirect-uri: true - WECHAT_ENTERPRISE: # 企业微信 - client-id: wwd411c69a39ad2e54 - client-secret: 1wTb7hYxnpT2TUbIeHGXGo7T0odav1ic10mLdyyATOw - agent-id: 1000004 - ignore-check-redirect-uri: true - WECHAT_MP: # 微信公众平台 - H5 https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index + type: + WECHAT_MP: # 微信公众平台 - 移动端 H5 https://www.yuque.com/docs/share/a795bef6-ee8a-494a-8dc4-2ef41927743b?#%20%E3%80%8A%E5%BE%AE%E4%BF%A1%E5%85%AC%E4%BC%97%E5%8F%B7%E6%B5%8B%E8%AF%95%E3%80%8B client-id: wxa5a05b85ac361f96 client-secret: 247073c7cebb67f27f0e769195c2a57e ignore-check-redirect-uri: true + WECHAT_MINI_PROGRAM: # 微信小程序 https://www.yuque.com/docs/share/88e3d30a-6830-45fc-8c25-dae485aef3aa?#%20%E3%80%8A%E5%B0%8F%E7%A8%8B%E5%BA%8F%E6%8E%88%E6%9D%83%E7%99%BB%E5%BD%95%E3%80%8B + client-id: wx44d047d87e6284d8 + client-secret: 21c3b7a8a51ee1b8f5cf875848ed4466 + ignore-check-redirect-uri: true + ignore-check-state: true cache: type: REDIS prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE:: diff --git a/yudao-user-server/src/main/resources/application-local.yaml b/yudao-user-server/src/main/resources/application-local.yaml index c39a7cb1b..3fc985282 100644 --- a/yudao-user-server/src/main/resources/application-local.yaml +++ b/yudao-user-server/src/main/resources/application-local.yaml @@ -165,17 +165,13 @@ justauth: # client-id: wx5b23ba7a5589ecbb # TODO 芋艿:自己的测试,后续可以删除 # client-secret: 2a7b3b20c537e52e74afd395eb85f61f ignore-check-redirect-uri: true - extend: - enum-class: cn.iocoder.yudao.coreservice.modules.system.compent.justauth.AuthExtendSource - config: - WECHAT_MINI_PROGRAM: # 微信小程序 https://www.yuque.com/docs/share/88e3d30a-6830-45fc-8c25-dae485aef3aa?#%20%E3%80%8A%E5%B0%8F%E7%A8%8B%E5%BA%8F%E6%8E%88%E6%9D%83%E7%99%BB%E5%BD%95%E3%80%8B - request-class: cn.iocoder.yudao.coreservice.modules.system.compent.justauth.AuthWeChatMiniProgramRequest - client-id: wx44d047d87e6284d8 - client-secret: 21c3b7a8a51ee1b8f5cf875848ed4466 -# client-id: wx63c280fe3248a3e7 # TODO 芋艿:自己的测试,后续可以删除 -# client-secret: 6f270509224a7ae1296bbf1c8cb97aed - ignore-check-redirect-uri: true - ignore-check-state: true + WECHAT_MINI_PROGRAM: # 微信小程序 https://www.yuque.com/docs/share/88e3d30a-6830-45fc-8c25-dae485aef3aa?#%20%E3%80%8A%E5%B0%8F%E7%A8%8B%E5%BA%8F%E6%8E%88%E6%9D%83%E7%99%BB%E5%BD%95%E3%80%8B + client-id: wx44d047d87e6284d8 + client-secret: 21c3b7a8a51ee1b8f5cf875848ed4466 + # client-id: wx63c280fe3248a3e7 # TODO 芋艿:自己的测试,后续可以删除 + # client-secret: 6f270509224a7ae1296bbf1c8cb97aed + ignore-check-redirect-uri: true + ignore-check-state: true cache: type: REDIS prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE:: From 65abc667b03086fe321fe13f0149fad61058a994 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 2 Nov 2021 08:12:37 +0800 Subject: [PATCH 02/41] =?UTF-8?q?code=20review=20=E7=A4=BE=E4=BA=A4?= =?UTF-8?q?=E7=99=BB=E9=99=86=E7=9B=B8=E5=85=B3=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modules/system/controller/auth/SysAuthController.java | 6 +++--- .../framework/social/core/YudaoAuthRequestFactory.java | 8 +++++--- .../framework/social/core/enums/AuthExtendSource.java | 3 +-- .../framework/social/core/model/AuthExtendToken.java | 4 ++-- .../social/core/request/AuthWeChatMiniProgramRequest.java | 1 + .../system/service/auth/impl/SysAuthServiceImpl.java | 2 +- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/auth/SysAuthController.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/auth/SysAuthController.java index c557b789a..aef8cc40a 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/auth/SysAuthController.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/auth/SysAuthController.java @@ -50,7 +50,7 @@ public class SysAuthController { @Resource private SysPermissionService permissionService; @Resource - private SysSocialCoreService socialService; + private SysSocialCoreService socialCoreService; @PostMapping("/login") @ApiOperation("使用账号密码登录") @@ -102,7 +102,7 @@ public class SysAuthController { }) public CommonResult socialAuthRedirect(@RequestParam("type") Integer type, @RequestParam("redirectUri") String redirectUri) { - return CommonResult.success(socialService.getAuthorizeUrl(type, redirectUri)); + return CommonResult.success(socialCoreService.getAuthorizeUrl(type, redirectUri)); } @PostMapping("/social-login") @@ -133,7 +133,7 @@ public class SysAuthController { @DeleteMapping("/social-unbind") @ApiOperation("取消社交绑定") public CommonResult socialUnbind(@RequestBody SysAuthSocialUnbindReqVO reqVO) { - socialService.unbindSocialUser(getLoginUserId(), reqVO.getType(), reqVO.getUnionId(), UserTypeEnum.ADMIN); + socialCoreService.unbindSocialUser(getLoginUserId(), reqVO.getType(), reqVO.getUnionId(), UserTypeEnum.ADMIN); return CommonResult.success(true); } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java index 998c70a12..17c36b683 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.framework.social.core; import cn.hutool.core.util.EnumUtil; -import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.social.core.enums.AuthExtendSource; import cn.iocoder.yudao.framework.social.core.request.AuthWeChatMiniProgramRequest; import com.xkcoding.http.config.HttpConfig; @@ -18,12 +17,14 @@ import java.net.Proxy; import java.util.Map; /** - * 第三方授权拓展request工厂类 + * 第三方授权拓展 request 工厂类 + * TODO @timfruit 可以说明下,为啥有了 AuthRequestFactory 类,咱还需要自定义 * * @author timfruit * @date 2021-10-31 */ public class YudaoAuthRequestFactory extends AuthRequestFactory { + protected JustAuthProperties properties; protected AuthStateCache authStateCache; @@ -34,7 +35,7 @@ public class YudaoAuthRequestFactory extends AuthRequestFactory { } /** - * 返回AuthRequest对象 + * 返回 AuthRequest 对象 * * @param source {@link AuthSource} * @return {@link AuthRequest} @@ -86,6 +87,7 @@ public class YudaoAuthRequestFactory extends AuthRequestFactory { * @param authConfig {@link AuthConfig} */ protected void configureHttpConfig(String authSource, AuthConfig authConfig, JustAuthProperties.JustAuthHttpConfig httpConfig) { + // TODO @timfruit:可以改成反射调用父类的方法。可能有一定的损耗,但是可以忽略不计的 if (null == httpConfig) { return; } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/enums/AuthExtendSource.java b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/enums/AuthExtendSource.java index bd19b8d06..fd6bb9cb9 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/enums/AuthExtendSource.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/enums/AuthExtendSource.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.framework.social.core.enums; import me.zhyd.oauth.config.AuthSource; +// TODO @timfruit:类注释 public enum AuthExtendSource implements AuthSource { /** @@ -28,6 +29,4 @@ public enum AuthExtendSource implements AuthSource { } } - ; - } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/model/AuthExtendToken.java b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/model/AuthExtendToken.java index 3397a4976..2c0f4f403 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/model/AuthExtendToken.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/model/AuthExtendToken.java @@ -4,7 +4,7 @@ import lombok.*; import me.zhyd.oauth.model.AuthToken; /** - * 授权所需的token 拓展类 + * 授权所需的 token 拓展类 * * @author timfruit * @date 2021-10-29 @@ -16,7 +16,7 @@ import me.zhyd.oauth.model.AuthToken; public class AuthExtendToken extends AuthToken { /** - * 微信小程序 会话密钥 + * 微信小程序 - 会话密钥 */ private String miniSessionKey; diff --git a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/request/AuthWeChatMiniProgramRequest.java b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/request/AuthWeChatMiniProgramRequest.java index a875c3b6e..ae9a8e1ec 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/request/AuthWeChatMiniProgramRequest.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/request/AuthWeChatMiniProgramRequest.java @@ -86,6 +86,7 @@ public class AuthWeChatMiniProgramRequest extends AuthDefaultRequest { .build(); } + // TODO @timfruit:我们要采用驼峰的命名方式。不匹配的,可以通过 jackson 的自定义注解映射 @Data private static class CodeSessionResponse { private int errcode; diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java index e4b938861..6ce205107 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java @@ -65,7 +65,7 @@ public class SysAuthServiceImpl implements SysAuthService { private SysUserSessionCoreService userSessionCoreService; @Resource private SysSocialCoreService socialService; - private static final UserTypeEnum USER_TYPE_ENUM = UserTypeEnum.MEMBER; + private static final UserTypeEnum USER_TYPE_ENUM = UserTypeEnum.MEMBER; // TODO @timfruit 挪到类的最前面。一般是 静态变量,到成员变量的顺序。 @Override public UserDetails loadUserByUsername(String mobile) throws UsernameNotFoundException { From 13a94050822b0862eca917ccb981a997e10fca57 Mon Sep 17 00:00:00 2001 From: timfruit Date: Fri, 5 Nov 2021 23:14:51 +0800 Subject: [PATCH 03/41] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/auth/impl/SysAuthServiceImpl.java | 3 +- .../social/core/YudaoAuthRequestFactory.java | 41 ++++--------------- .../social/core/enums/AuthExtendSource.java | 6 ++- .../request/AuthWeChatMiniProgramRequest.java | 7 ++-- .../service/auth/impl/SysAuthServiceImpl.java | 4 +- 5 files changed, 21 insertions(+), 40 deletions(-) diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java index abb6a3dca..3552dd9a4 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java @@ -56,6 +56,8 @@ import static java.util.Collections.singleton; @Slf4j public class SysAuthServiceImpl implements SysAuthService { + private static final UserTypeEnum USER_TYPE_ENUM = UserTypeEnum.ADMIN; + @Resource @Lazy // 延迟加载,因为存在相互依赖的问题 private AuthenticationManager authenticationManager; @@ -75,7 +77,6 @@ public class SysAuthServiceImpl implements SysAuthService { @Resource private SysSocialCoreService socialService; - private static final UserTypeEnum USER_TYPE_ENUM = UserTypeEnum.ADMIN; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { diff --git a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java index 17c36b683..26e23b9d7 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java @@ -1,24 +1,21 @@ package cn.iocoder.yudao.framework.social.core; import cn.hutool.core.util.EnumUtil; +import cn.hutool.core.util.ReflectUtil; import cn.iocoder.yudao.framework.social.core.enums.AuthExtendSource; import cn.iocoder.yudao.framework.social.core.request.AuthWeChatMiniProgramRequest; -import com.xkcoding.http.config.HttpConfig; import com.xkcoding.justauth.AuthRequestFactory; import com.xkcoding.justauth.autoconfigure.JustAuthProperties; import me.zhyd.oauth.cache.AuthStateCache; import me.zhyd.oauth.config.AuthConfig; import me.zhyd.oauth.config.AuthSource; import me.zhyd.oauth.request.AuthRequest; -import org.springframework.util.CollectionUtils; -import java.net.InetSocketAddress; -import java.net.Proxy; -import java.util.Map; +import java.lang.reflect.Method; /** * 第三方授权拓展 request 工厂类 - * TODO @timfruit 可以说明下,为啥有了 AuthRequestFactory 类,咱还需要自定义 + * (为使得拓展配置和默认配置齐平,自定义本工厂类) * * @author timfruit * @date 2021-10-31 @@ -70,7 +67,10 @@ public class YudaoAuthRequestFactory extends AuthRequestFactory { } // 配置 http config - configureHttpConfig(authExtendSource.name(), config, properties.getHttpConfig()); + Method method = ReflectUtil.getMethod(AuthRequestFactory.class, "configureHttpConfig", + String.class, AuthConfig.class, JustAuthProperties.JustAuthHttpConfig.class); + ReflectUtil.invoke(this, method, + authExtendSource.name(), config, properties.getHttpConfig()); switch (authExtendSource) { case WECHAT_MINI_PROGRAM: @@ -80,31 +80,4 @@ public class YudaoAuthRequestFactory extends AuthRequestFactory { } } - /** - * 配置 http 相关的配置 - * - * @param authSource {@link AuthSource} - * @param authConfig {@link AuthConfig} - */ - protected void configureHttpConfig(String authSource, AuthConfig authConfig, JustAuthProperties.JustAuthHttpConfig httpConfig) { - // TODO @timfruit:可以改成反射调用父类的方法。可能有一定的损耗,但是可以忽略不计的 - if (null == httpConfig) { - return; - } - Map proxyConfigMap = httpConfig.getProxy(); - if (CollectionUtils.isEmpty(proxyConfigMap)) { - return; - } - JustAuthProperties.JustAuthProxyConfig proxyConfig = proxyConfigMap.get(authSource); - - if (null == proxyConfig) { - return; - } - - authConfig.setHttpConfig(HttpConfig.builder() - .timeout(httpConfig.getTimeout()) - .proxy(new Proxy(Proxy.Type.valueOf(proxyConfig.getType()), new InetSocketAddress(proxyConfig.getHostname(), proxyConfig.getPort()))) - .build()); - } - } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/enums/AuthExtendSource.java b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/enums/AuthExtendSource.java index fd6bb9cb9..16049419f 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/enums/AuthExtendSource.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/enums/AuthExtendSource.java @@ -2,7 +2,11 @@ package cn.iocoder.yudao.framework.social.core.enums; import me.zhyd.oauth.config.AuthSource; -// TODO @timfruit:类注释 +/** + * 拓展JustAuth各api需要的url, 用枚举类分平台类型管理
+ * + * 默认配置{@link me.zhyd.oauth.config.AuthDefaultSource} + */ public enum AuthExtendSource implements AuthSource { /** diff --git a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/request/AuthWeChatMiniProgramRequest.java b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/request/AuthWeChatMiniProgramRequest.java index ae9a8e1ec..e5bbfcaad 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/request/AuthWeChatMiniProgramRequest.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/request/AuthWeChatMiniProgramRequest.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.social.core.request; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.social.core.enums.AuthExtendSource; import cn.iocoder.yudao.framework.social.core.model.AuthExtendToken; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import me.zhyd.oauth.cache.AuthStateCache; import me.zhyd.oauth.config.AuthConfig; @@ -39,7 +40,7 @@ public class AuthWeChatMiniProgramRequest extends AuthDefaultRequest { this.checkResponse(accessTokenObject); AuthExtendToken token = new AuthExtendToken(); - token.setMiniSessionKey(accessTokenObject.session_key); + token.setMiniSessionKey(accessTokenObject.sessionKey); token.setOpenId(accessTokenObject.openid); token.setUnionId(accessTokenObject.unionid); return token; @@ -86,12 +87,12 @@ public class AuthWeChatMiniProgramRequest extends AuthDefaultRequest { .build(); } - // TODO @timfruit:我们要采用驼峰的命名方式。不匹配的,可以通过 jackson 的自定义注解映射 @Data private static class CodeSessionResponse { private int errcode; private String errmsg; - private String session_key; + @JsonProperty("session_key") + private String sessionKey; private String openid; private String unionid; } diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java index 6ce205107..c5c512890 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/system/service/auth/impl/SysAuthServiceImpl.java @@ -51,6 +51,8 @@ import static cn.iocoder.yudao.userserver.modules.system.enums.SysErrorCodeConst @Slf4j public class SysAuthServiceImpl implements SysAuthService { + private static final UserTypeEnum USER_TYPE_ENUM = UserTypeEnum.MEMBER; + @Resource @Lazy // 延迟加载,因为存在相互依赖的问题 private AuthenticationManager authenticationManager; @@ -65,7 +67,7 @@ public class SysAuthServiceImpl implements SysAuthService { private SysUserSessionCoreService userSessionCoreService; @Resource private SysSocialCoreService socialService; - private static final UserTypeEnum USER_TYPE_ENUM = UserTypeEnum.MEMBER; // TODO @timfruit 挪到类的最前面。一般是 静态变量,到成员变量的顺序。 + @Override public UserDetails loadUserByUsername(String mobile) throws UsernameNotFoundException { From 7c8fe2fc50dcdc6f625d7420f7c9911f70eaf822 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 4 Dec 2021 21:09:49 +0800 Subject: [PATCH 04/41] =?UTF-8?q?1.=20=E5=A2=9E=E5=8A=A0=20yudao-spring-bo?= =?UTF-8?q?ot-starter-tenant=20=E7=A7=9F=E6=88=B7=E7=9A=84=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=202.=20=E6=94=B9=E9=80=A0=20UserDO=EF=BC=8C=E6=8E=A5?= =?UTF-8?q?=E5=85=A5=E5=A4=9A=E7=A7=9F=E6=88=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-admin-server/pom.xml | 5 ++ .../controller/auth/SysAuthController.http | 3 +- .../captcha/config/CaptchaProperties.java | 7 +++ .../service/auth/impl/SysAuthServiceImpl.java | 6 ++- .../service/common/SysCaptchaService.java | 7 +++ .../common/impl/SysCaptchaServiceImpl.java | 5 ++ .../src/main/resources/application-local.yaml | 2 + .../src/main/resources/application.yaml | 2 + .../service/auth/SysAuthServiceImplTest.java | 6 +++ .../service/user/SysUserServiceImplTest.java | 1 + .../src/test/resources/sql/create_tables.sql | 1 + yudao-core-service/pom.xml | 5 ++ .../system/dal/dataobject/user/SysUserDO.java | 4 +- yudao-dependencies/pom.xml | 13 +++++ yudao-framework/pom.xml | 1 + yudao-framework/yudao-common/pom.xml | 11 +++++ .../common/enums/WebFilterOrderEnum.java | 6 ++- .../mybatis/core/dataobject/BaseDO.java | 4 +- .../mybatis/core/util/MyBatisUtils.java | 17 +++++++ .../yudao-spring-boot-starter-tenant/pom.xml | 37 ++++++++++++++ .../tenant/config/TenantProperties.java | 25 ++++++++++ .../YudaoTenantDatabaseAutoConfiguration.java | 43 +++++++++++++++++ .../YudaoTenantWebAutoConfiguration.java | 23 +++++++++ .../core/context/TenantContextHolder.java | 26 ++++++++++ .../tenant/core/db/TenantBaseDO.java | 21 ++++++++ .../core/db/TenantDatabaseInterceptor.java | 33 +++++++++++++ .../tenant/core/web/TenantWebFilter.java | 39 +++++++++++++++ .../yudao/framework/tenant/package-info.java | 8 ++++ .../main/resources/META-INF/spring.factories | 3 ++ .../user/SysUserProfileController.java | 4 +- .../member/service/user/MbrUserService.java | 4 +- .../service/user/impl/MbrUserServiceImpl.java | 6 +-- yudao-vue-ui/api/member/userProfile.js | 14 ++++++ yudao-vue-ui/common/js/request.js | 1 + yudao-vue-ui/pages/set/userInfo.vue | 48 ++++++++++++++++++- 35 files changed, 426 insertions(+), 15 deletions(-) create mode 100644 yudao-framework/yudao-spring-boot-starter-tenant/pom.xml create mode 100644 yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/TenantProperties.java create mode 100644 yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantDatabaseAutoConfiguration.java create mode 100644 yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantWebAutoConfiguration.java create mode 100644 yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/context/TenantContextHolder.java create mode 100644 yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantBaseDO.java create mode 100644 yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantDatabaseInterceptor.java create mode 100644 yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/web/TenantWebFilter.java create mode 100644 yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/package-info.java create mode 100644 yudao-framework/yudao-spring-boot-starter-tenant/src/main/resources/META-INF/spring.factories diff --git a/yudao-admin-server/pom.xml b/yudao-admin-server/pom.xml index 4314e0fed..f3b91ac0f 100644 --- a/yudao-admin-server/pom.xml +++ b/yudao-admin-server/pom.xml @@ -117,6 +117,11 @@ yudao-spring-boot-starter-excel
+ + cn.iocoder.boot + yudao-spring-boot-starter-tenant + + org.apache.velocity velocity-engine-core diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/auth/SysAuthController.http b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/auth/SysAuthController.http index 125a36846..580b897f8 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/auth/SysAuthController.http +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/controller/auth/SysAuthController.http @@ -1,11 +1,12 @@ ### 请求 /login 接口 => 成功 POST {{baseUrl}}/login Content-Type: application/json +tenant-id: 0 { "username": "admin", "password": "admin123", - "uuid": "9b2ffbc1-7425-4155-9894-9d5c08541d62", + "uuid": "3acd87a09a4f48fb9118333780e94883", "code": "1024" } diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/framework/captcha/config/CaptchaProperties.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/framework/captcha/config/CaptchaProperties.java index 6eadd4d12..73939df75 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/framework/captcha/config/CaptchaProperties.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/framework/captcha/config/CaptchaProperties.java @@ -12,6 +12,13 @@ import java.time.Duration; @Data public class CaptchaProperties { + private static final Boolean ENABLE_DEFAULT = true; + + /** + * 是否开启 + * 注意,这里仅仅是后端 Server 是否校验,暂时不控制前端的逻辑 + */ + private Boolean enable = ENABLE_DEFAULT; /** * 验证码的过期时间 */ diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java index 762649d9d..2804b2813 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/impl/SysAuthServiceImpl.java @@ -133,9 +133,13 @@ public class SysAuthServiceImpl implements SysAuthService { } private void verifyCaptcha(String username, String captchaUUID, String captchaCode) { + // 如果验证码关闭,则不进行校验 + if (!captchaService.isCaptchaEnable()) { + return; + } + // 验证码不存在 final SysLoginLogTypeEnum logTypeEnum = SysLoginLogTypeEnum.LOGIN_USERNAME; String code = captchaService.getCaptchaCode(captchaUUID); - // 验证码不存在 if (code == null) { // 创建登录失败日志(验证码不存在) this.createLoginLog(username, logTypeEnum, SysLoginResultEnum.CAPTCHA_NOT_FOUND); diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/common/SysCaptchaService.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/common/SysCaptchaService.java index 286a5ef1f..32aff5b06 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/common/SysCaptchaService.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/common/SysCaptchaService.java @@ -14,6 +14,13 @@ public interface SysCaptchaService { */ SysCaptchaImageRespVO getCaptchaImage(); + /** + * 是否开启图片验证码 + * + * @return 是否 + */ + Boolean isCaptchaEnable(); + /** * 获得 uuid 对应的验证码 * diff --git a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/common/impl/SysCaptchaServiceImpl.java b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/common/impl/SysCaptchaServiceImpl.java index 44d291ffd..daefc007f 100644 --- a/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/common/impl/SysCaptchaServiceImpl.java +++ b/yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/common/impl/SysCaptchaServiceImpl.java @@ -35,6 +35,11 @@ public class SysCaptchaServiceImpl implements SysCaptchaService { return SysCaptchaConvert.INSTANCE.convert(uuid, captcha); } + @Override + public Boolean isCaptchaEnable() { + return captchaProperties.getEnable(); + } + @Override public String getCaptchaCode(String uuid) { return captchaRedisDAO.get(uuid); diff --git a/yudao-admin-server/src/main/resources/application-local.yaml b/yudao-admin-server/src/main/resources/application-local.yaml index d7880547f..79fdb300c 100644 --- a/yudao-admin-server/src/main/resources/application-local.yaml +++ b/yudao-admin-server/src/main/resources/application-local.yaml @@ -166,6 +166,8 @@ logging: # 芋道配置项,设置当前项目所有自定义的配置 yudao: + captcha: + enable: false # 本地环境,暂时关闭图片验证码,方便登录等接口的测试 security: token-header: Authorization token-secret: abcdefghijklmnopqrstuvwxyz diff --git a/yudao-admin-server/src/main/resources/application.yaml b/yudao-admin-server/src/main/resources/application.yaml index 8674452cf..f71a66fc6 100644 --- a/yudao-admin-server/src/main/resources/application.yaml +++ b/yudao-admin-server/src/main/resources/application.yaml @@ -73,5 +73,7 @@ yudao: constants-class-list: - cn.iocoder.yudao.adminserver.modules.infra.enums.InfErrorCodeConstants - cn.iocoder.yudao.adminserver.modules.system.enums.SysErrorCodeConstants + tenant: + tables: sys_user debug: false diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/SysAuthServiceImplTest.java b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/SysAuthServiceImplTest.java index 59be97809..492128e6b 100644 --- a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/SysAuthServiceImplTest.java +++ b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/auth/SysAuthServiceImplTest.java @@ -17,6 +17,7 @@ import cn.iocoder.yudao.coreservice.modules.system.service.user.SysUserCoreServi import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.security.core.LoginUser; import cn.iocoder.yudao.framework.test.core.util.AssertUtils; +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; @@ -71,6 +72,11 @@ public class SysAuthServiceImplTest extends BaseDbUnitTest { @MockBean private SysPostService postService; + @BeforeEach + public void setUp() { + when(captchaService.isCaptchaEnable()).thenReturn(true); + } + @Test public void testLoadUserByUsername_success() { // 准备参数 diff --git a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/user/SysUserServiceImplTest.java b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/user/SysUserServiceImplTest.java index 70751eeac..cd1faa592 100644 --- a/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/user/SysUserServiceImplTest.java +++ b/yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/user/SysUserServiceImplTest.java @@ -21,6 +21,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; +import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import org.junit.jupiter.api.Test; import org.mockito.stubbing.Answer; import org.springframework.boot.test.mock.mockito.MockBean; diff --git a/yudao-admin-server/src/test/resources/sql/create_tables.sql b/yudao-admin-server/src/test/resources/sql/create_tables.sql index db67cad23..96157b3d9 100644 --- a/yudao-admin-server/src/test/resources/sql/create_tables.sql +++ b/yudao-admin-server/src/test/resources/sql/create_tables.sql @@ -287,6 +287,7 @@ CREATE TABLE IF NOT EXISTS "sys_user" ( "updater" varchar(64) default '', "update_time" timestamp not null default current_timestamp, "deleted" bit not null default false, + "tenant_id" bigint not null default '0', primary key ("id") ) comment '用户信息表'; diff --git a/yudao-core-service/pom.xml b/yudao-core-service/pom.xml index 4fd85c0aa..4be7e2e30 100644 --- a/yudao-core-service/pom.xml +++ b/yudao-core-service/pom.xml @@ -91,6 +91,11 @@ + + cn.iocoder.boot + yudao-spring-boot-starter-tenant + + com.google.guava guava diff --git a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/dal/dataobject/user/SysUserDO.java b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/dal/dataobject/user/SysUserDO.java index ef33f8d2a..bb5e6854c 100644 --- a/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/dal/dataobject/user/SysUserDO.java +++ b/yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/system/dal/dataobject/user/SysUserDO.java @@ -2,8 +2,8 @@ package cn.iocoder.yudao.coreservice.modules.system.dal.dataobject.user; import cn.iocoder.yudao.coreservice.modules.system.enums.common.SysSexEnum; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler; +import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -24,7 +24,7 @@ import java.util.Set; @Builder @NoArgsConstructor @AllArgsConstructor -public class SysUserDO extends BaseDO { +public class SysUserDO extends TenantBaseDO { /** * 用户ID diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index cd5efec94..8d94d04c8 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -48,6 +48,7 @@ 2.2 1.0.5 30.1.1-jre + 2.12.2 4.5.25 2.1.0 @@ -350,6 +351,12 @@ ${revision} + + cn.iocoder.boot + yudao-spring-boot-starter-tenant + ${revision} + + org.projectlombok lombok @@ -402,6 +409,12 @@ ${guava.version} + + com.alibaba + transmittable-thread-local + ${transmittable-thread-local.version} + + diff --git a/yudao-framework/pom.xml b/yudao-framework/pom.xml index 136ac3073..63fc2c33c 100644 --- a/yudao-framework/pom.xml +++ b/yudao-framework/pom.xml @@ -32,6 +32,7 @@ yudao-spring-boot-starter-biz-pay yudao-spring-boot-starter-biz-weixin yudao-spring-boot-starter-extension + yudao-spring-boot-starter-tenant yudao-framework diff --git a/yudao-framework/yudao-common/pom.xml b/yudao-framework/yudao-common/pom.xml index ad84d6a24..2681c8914 100644 --- a/yudao-framework/yudao-common/pom.xml +++ b/yudao-framework/yudao-common/pom.xml @@ -122,6 +122,17 @@ jakarta.validation-api provided + + + cn.hutool + hutool-all + + + + com.alibaba + transmittable-thread-local + + diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java index 6ad94a369..1d8cc4034 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/WebFilterOrderEnum.java @@ -17,9 +17,11 @@ public interface WebFilterOrderEnum { // OrderedRequestContextFilter 默认为 -105,用于国际化上下文等等 - int API_ACCESS_LOG_FILTER = -104; // 需要保证在 RequestBodyCacheFilter 后面 + int TENANT_FILTER = - 100; // 需要保证在 ApiAccessLogFilter 前面 - int XSS_FILTER = -103; // 需要保证在 RequestBodyCacheFilter 后面 + int API_ACCESS_LOG_FILTER = -90; // 需要保证在 RequestBodyCacheFilter 后面 + + int XSS_FILTER = -80; // 需要保证在 RequestBodyCacheFilter 后面 // Spring Security Filter 默认为 -100,可见 SecurityProperties 配置属性类 diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/dataobject/BaseDO.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/dataobject/BaseDO.java index 15d99a3d8..f63f054de 100644 --- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/dataobject/BaseDO.java +++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/dataobject/BaseDO.java @@ -10,9 +10,11 @@ import java.util.Date; /** * 基础实体对象 + * + * @author 芋道源码 */ @Data -public class BaseDO implements Serializable { +public abstract class BaseDO implements Serializable { /** * 创建时间 diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/MyBatisUtils.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/MyBatisUtils.java index 3c455e893..8789ea574 100644 --- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/MyBatisUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/MyBatisUtils.java @@ -4,9 +4,13 @@ import cn.hutool.core.collection.CollectionUtil; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.SortingField; import com.baomidou.mybatisplus.core.metadata.OrderItem; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; import java.util.stream.Collectors; /** @@ -30,4 +34,17 @@ public class MyBatisUtils { return page; } + /** + * 将拦截器添加到链中 + * 由于 MybatisPlusInterceptor 不支持添加拦截器,所以只能全量设置 + * + * @param interceptor 链 + * @param inner 拦截器 + */ + public static void addInterceptor(MybatisPlusInterceptor interceptor, InnerInterceptor inner) { + List inners = new ArrayList<>(interceptor.getInterceptors()); + inners.add(0, inner); + interceptor.setInterceptors(inners); + } + } diff --git a/yudao-framework/yudao-spring-boot-starter-tenant/pom.xml b/yudao-framework/yudao-spring-boot-starter-tenant/pom.xml new file mode 100644 index 000000000..854db0bbf --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-tenant/pom.xml @@ -0,0 +1,37 @@ + + + + yudao-framework + cn.iocoder.boot + ${revision} + + 4.0.0 + yudao-spring-boot-starter-tenant + jar + + ${artifactId} + 多租户 + https://github.com/YunaiV/ruoyi-vue-pro + + + + cn.iocoder.boot + yudao-common + + + + + org.springframework.boot + spring-boot-starter-web + + + + + cn.iocoder.boot + yudao-spring-boot-starter-mybatis + + + + diff --git a/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/TenantProperties.java b/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/TenantProperties.java new file mode 100644 index 000000000..5b97b22f6 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/TenantProperties.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.framework.tenant.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import java.util.Set; + +/** + * 多租户配置 + * + * @author 芋道源码 + */ +@ConfigurationProperties(prefix = "yudao.tenant") +@Data +public class TenantProperties { + + /** + * 需要多租户的表 + * + * 由于多租户并不作为 yudao 项目的重点功能,更多是扩展性的功能,所以采用正向配置需要多租户的表。 + * 如果需要,你可以改成 ignoreTables 来取消部分不需要的表 + */ + private Set tables; + +} diff --git a/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantDatabaseAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantDatabaseAutoConfiguration.java new file mode 100644 index 000000000..7149e39a2 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantDatabaseAutoConfiguration.java @@ -0,0 +1,43 @@ +package cn.iocoder.yudao.framework.tenant.config; + +import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; +import cn.iocoder.yudao.framework.tenant.core.db.TenantDatabaseInterceptor; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; + +/** + * 多租户针对 DB 的自动配置 + * + * @author 芋道源码 + */ +@EnableConfigurationProperties(TenantProperties.class) +public class YudaoTenantDatabaseAutoConfiguration { + + @Bean + public TenantLineInnerInterceptor tenantLineInnerInterceptor(TenantProperties properties) { + return new TenantLineInnerInterceptor(new TenantDatabaseInterceptor(properties)); + } + + @Bean + public BeanPostProcessor mybatisPlusInterceptorBeanPostProcessor(TenantLineInnerInterceptor tenantLineInnerInterceptor) { + return new BeanPostProcessor() { + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + if (!(bean instanceof MybatisPlusInterceptor)) { + return bean; + } + // 将 TenantDatabaseInterceptor 添加到最前面 + MybatisPlusInterceptor interceptor = (MybatisPlusInterceptor) bean; + MyBatisUtils.addInterceptor(interceptor, tenantLineInnerInterceptor); + return bean; + } + + }; + } + +} diff --git a/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantWebAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantWebAutoConfiguration.java new file mode 100644 index 000000000..7b2e1aaf5 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantWebAutoConfiguration.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.framework.tenant.config; + +import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; +import cn.iocoder.yudao.framework.tenant.core.web.TenantWebFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; + +/** + * 多租户针对 Web 的自动配置 + * + * @author 芋道源码 + */ +public class YudaoTenantWebAutoConfiguration { + + @Bean + public FilterRegistrationBean tenantWebFilter() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(new TenantWebFilter()); + registrationBean.setOrder(WebFilterOrderEnum.TENANT_FILTER); + return registrationBean; + } + +} diff --git a/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/context/TenantContextHolder.java b/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/context/TenantContextHolder.java new file mode 100644 index 000000000..92dbff002 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/context/TenantContextHolder.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.framework.tenant.core.context; + +import com.alibaba.ttl.TransmittableThreadLocal; + +/** + * 多租户上下文 Holder + * + * @author 芋道源码 + */ +public class TenantContextHolder { + + private static final ThreadLocal TENANT_ID = new TransmittableThreadLocal<>(); + + public static Long getTenantId() { + return TENANT_ID.get(); + } + + public static void setTenantId(Long tenantId) { + TENANT_ID.set(tenantId); + } + + public static void clear() { + TENANT_ID.remove(); + } + +} diff --git a/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantBaseDO.java b/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantBaseDO.java new file mode 100644 index 000000000..f4f0ea50a --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantBaseDO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.framework.tenant.core.db; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 拓展多租户的 BaseDO 基类 + * + * @author 芋道源码 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public abstract class TenantBaseDO extends BaseDO { + + /** + * 多租户编号 + */ + private Long tenantId; + +} diff --git a/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantDatabaseInterceptor.java b/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantDatabaseInterceptor.java new file mode 100644 index 000000000..dfcd8a4a4 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/db/TenantDatabaseInterceptor.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.framework.tenant.core.db; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.tenant.config.TenantProperties; +import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; +import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler; +import lombok.AllArgsConstructor; +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.expression.StringValue; + +/** + * 基于 MyBatis Plus 多租户的功能,实现 DB 层面的多租户的功能 + * + * @author 芋道源码 + */ +@AllArgsConstructor +public class TenantDatabaseInterceptor implements TenantLineHandler { + + private final TenantProperties properties; + + @Override + public Expression getTenantId() { + // TODO 芋艿:暂时不考虑获取不到的情况。此时,会存在 NPE 的报错 + return new StringValue(TenantContextHolder.getTenantId().toString()); + } + + @Override + public boolean ignoreTable(String tableName) { + // 不包含,说明要过滤 + return !CollUtil.contains(properties.getTables(), tableName); + } + +} diff --git a/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/web/TenantWebFilter.java b/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/web/TenantWebFilter.java new file mode 100644 index 000000000..027656476 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/web/TenantWebFilter.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.framework.tenant.core.web; + +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 多租户 Web 过滤器 + * 将请求 Header 中的 tenant-id 解析出来,添加到 {@link TenantContextHolder} 中,这样后续的 DB 等操作,可以获得到租户编号 + * + * @author 芋道源码 + */ +public class TenantWebFilter extends OncePerRequestFilter { + + private static final String HEADER_TENANT_ID = "tenant-id"; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) + throws ServletException, IOException { + // 设置 + String tenantId = request.getHeader(HEADER_TENANT_ID); + if (StrUtil.isNotEmpty(tenantId)) { + TenantContextHolder.setTenantId(Long.valueOf(tenantId)); + } + try { + chain.doFilter(request, response); + } finally { + // 清理 + TenantContextHolder.clear(); + } + } + +} diff --git a/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/package-info.java b/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/package-info.java new file mode 100644 index 000000000..1f39db41f --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/package-info.java @@ -0,0 +1,8 @@ +/** + * 多租户,支持如下层面: + * 1. DB:基于 MyBatis Plus 多租户的功能实现 + * 2. Job:TODO + * 3. MQ:TODO + * 4. Web:TODO + */ +package cn.iocoder.yudao.framework.tenant; diff --git a/yudao-framework/yudao-spring-boot-starter-tenant/src/main/resources/META-INF/spring.factories b/yudao-framework/yudao-spring-boot-starter-tenant/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000..6f0a6f12b --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-tenant/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + cn.iocoder.yudao.framework.tenant.config.YudaoTenantDatabaseAutoConfiguration,\ + cn.iocoder.yudao.framework.tenant.config.YudaoTenantWebAutoConfiguration diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.java index 93149e793..c0778184a 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/controller/user/SysUserProfileController.java @@ -41,8 +41,8 @@ public class SysUserProfileController { @PutMapping("/update-nickname") @ApiOperation("修改用户昵称") @PreAuthenticated - public CommonResult updateNickname(@RequestParam("nickName") String nickName) { - userService.updateNickname(getLoginUserId(), nickName); + public CommonResult updateNickname(@RequestParam("nickname") String nickname) { + userService.updateNickname(getLoginUserId(), nickname); return success(true); } diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/MbrUserService.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/MbrUserService.java index fc5a8564d..e33978bfe 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/MbrUserService.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/MbrUserService.java @@ -51,9 +51,9 @@ public interface MbrUserService { /** * 修改用户昵称 * @param userId 用户id - * @param nickName 用户新昵称 + * @param nickname 用户新昵称 */ - void updateNickname(Long userId, String nickName); + void updateNickname(Long userId, String nickname); /** * 修改用户头像 diff --git a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/impl/MbrUserServiceImpl.java b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/impl/MbrUserServiceImpl.java index 40b7b862b..442da4147 100644 --- a/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/impl/MbrUserServiceImpl.java +++ b/yudao-user-server/src/main/java/cn/iocoder/yudao/userserver/modules/member/service/user/impl/MbrUserServiceImpl.java @@ -86,15 +86,15 @@ public class MbrUserServiceImpl implements MbrUserService { } @Override - public void updateNickname(Long userId, String nickName) { + public void updateNickname(Long userId, String nickname) { MbrUserDO user = this.checkUserExists(userId); // 仅当新昵称不等于旧昵称时进行修改 - if (nickName.equals(user.getNickname())){ + if (nickname.equals(user.getNickname())){ return; } MbrUserDO userDO = new MbrUserDO(); userDO.setId(user.getId()); - userDO.setNickname(nickName); + userDO.setNickname(nickname); userMapper.updateById(userDO); } diff --git a/yudao-vue-ui/api/member/userProfile.js b/yudao-vue-ui/api/member/userProfile.js index 3c3d52e71..2effa1eb7 100644 --- a/yudao-vue-ui/api/member/userProfile.js +++ b/yudao-vue-ui/api/member/userProfile.js @@ -6,4 +6,18 @@ export function getUserInfo() { url: 'member/user/profile/get', method: 'get' }) +} + +// 修改 +export function updateNickname(nickname) { + return request({ + url: 'member/user/profile/update-nickname', + method: 'post', + header: { + "Content-Type": "application/x-www-form-urlencoded" + }, + data: { + nickname + } + }) } \ No newline at end of file diff --git a/yudao-vue-ui/common/js/request.js b/yudao-vue-ui/common/js/request.js index 7f3d04bae..d78866e4e 100644 --- a/yudao-vue-ui/common/js/request.js +++ b/yudao-vue-ui/common/js/request.js @@ -12,6 +12,7 @@ export const request = (options) => { method: options.method || 'GET', data: options.data || {}, header: { + ...options.header, 'Authorization': authToken ? `Bearer ${authToken}` : '' } }).then(res => { diff --git a/yudao-vue-ui/pages/set/userInfo.vue b/yudao-vue-ui/pages/set/userInfo.vue index 07eae7e2f..4d46ed8a8 100644 --- a/yudao-vue-ui/pages/set/userInfo.vue +++ b/yudao-vue-ui/pages/set/userInfo.vue @@ -20,8 +20,20 @@ 昵称 + + + + + + + + + + + + + - @@ -32,6 +44,16 @@ uploadProgress: 100, //头像上传进度 tempAvatar: '', userInfo: {}, + nicknameOpen: false, + nicknameForm: { + nickname: '' + }, + nicknameRules: { + nickname: [{ + required: true, + message: '请输入昵称' + }] + } } }, computed: { @@ -50,6 +72,30 @@ this.userInfo = {avatar, nickname, gender}; }, methods: { + nicknameClick() { + this.nicknameOpen = true; + this.nicknameForm.nickname = this.userInfo.nickname; + }, + nicknameCancel() { + this.nicknameOpen = false; + }, + nicknameSubmit() { + this.$refs.nicknameForm.validate().then(() => { + this.loading = true; + // 执行登陆 + const { mobile, code, password} = this.form; + const loginPromise = this.loginType == 'password' ? login(mobile, password) : + smsLogin(mobile, code); + loginPromise.then(data => { + // 登陆成功 + this.loginSuccessCallBack(data); + }).catch(errors => { + }).finally(() => { + this.loading = false; + }) + }).catch(errors => { + }); + }, // 提交修改 async confirm() { // 校验信息是否变化 From 0cb4823b5b0ad5668a801da0def2b7d9296f9cbd Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 4 Dec 2021 23:27:39 +0800 Subject: [PATCH 05/41] =?UTF-8?q?1.=20=E5=89=8D=E7=AB=AF=E7=99=BB=E9=99=86?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=EF=BC=8C=E6=8E=A5=E5=85=A5=E7=A7=9F=E6=88=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-admin-ui/src/utils/request.js | 6 ++++++ yudao-admin-ui/src/views/login.vue | 19 +++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/yudao-admin-ui/src/utils/request.js b/yudao-admin-ui/src/utils/request.js index c063ec300..4daa6e464 100644 --- a/yudao-admin-ui/src/utils/request.js +++ b/yudao-admin-ui/src/utils/request.js @@ -3,6 +3,7 @@ import { Notification, MessageBox, Message } from 'element-ui' import store from '@/store' import { getToken } from '@/utils/auth' import errorCode from '@/utils/errorCode' +import Cookies from "js-cookie"; axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' // 创建axios实例 @@ -19,6 +20,11 @@ service.interceptors.request.use(config => { if (getToken() && !isToken) { config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 } + // 设置租户 + const tenantId = Cookies.get('tenantId'); + if (tenantId) { + config.headers['tenant-id'] = tenantId; + } // get请求映射params参数 if (config.method === 'get' && config.params) { let url = config.url + '?'; diff --git a/yudao-admin-ui/src/views/login.vue b/yudao-admin-ui/src/views/login.vue index d963e24c3..b098e13ad 100644 --- a/yudao-admin-ui/src/views/login.vue +++ b/yudao-admin-ui/src/views/login.vue @@ -2,6 +2,11 @@