mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 23:31:52 +08:00
Merge branch 'master' of https://gitee.com/zhijiantianya/ruoyi-vue-pro
Conflicts: yudao-core-service/pom.xml yudao-dependencies/pom.xml yudao-framework/pom.xml
This commit is contained in:
commit
a55c0cfca5
@ -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 socialCoreService;
|
||||
|
||||
@PostMapping("/login")
|
||||
@ApiOperation("使用账号密码登录")
|
||||
@ -102,7 +102,7 @@ public class SysAuthController {
|
||||
})
|
||||
public CommonResult<String> 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<Boolean> 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);
|
||||
}
|
||||
|
||||
|
@ -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("获得登录用户信息")
|
||||
|
@ -19,7 +19,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;
|
||||
@ -60,6 +60,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;
|
||||
@ -79,10 +81,8 @@ public class SysAuthServiceImpl implements SysAuthService {
|
||||
@Resource
|
||||
private SysPostService postService;
|
||||
@Resource
|
||||
private SysSocialService socialService;
|
||||
private SysSocialCoreService socialService;
|
||||
|
||||
// TODO @timfruit:静态枚举类,需要都大写,例如说 USER_TYPE_ENUM;静态变量,放在普通变量前面;这个实践不错哈。
|
||||
private static final UserTypeEnum userTypeEnum = UserTypeEnum.ADMIN;
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
@ -216,7 +216,7 @@ public class SysAuthServiceImpl implements SysAuthService {
|
||||
|
||||
// 如果未绑定 SysSocialUserDO 用户,则无法自动登录,进行报错
|
||||
String unionId = socialService.getAuthUserUnionId(authUser);
|
||||
List<SysSocialUserDO> socialUsers = socialService.getAllSocialUserList(reqVO.getType(), unionId, userTypeEnum);
|
||||
List<SysSocialUserDO> socialUsers = socialService.getAllSocialUserList(reqVO.getType(), unionId, USER_TYPE_ENUM);
|
||||
if (CollUtil.isEmpty(socialUsers)) {
|
||||
throw exception(AUTH_THIRD_LOGIN_NOT_BIND);
|
||||
}
|
||||
@ -232,7 +232,7 @@ public class SysAuthServiceImpl implements SysAuthService {
|
||||
LoginUser loginUser = this.buildLoginUser(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);
|
||||
@ -248,7 +248,7 @@ public class SysAuthServiceImpl implements SysAuthService {
|
||||
LoginUser loginUser = this.login0(reqVO.getUsername(), reqVO.getPassword());
|
||||
|
||||
// 绑定社交用户(新增)
|
||||
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);
|
||||
@ -261,7 +261,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
|
||||
@ -282,7 +282,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());
|
||||
|
@ -12,7 +12,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;
|
||||
@ -68,7 +68,7 @@ public class SysAuthServiceImplTest extends BaseDbUnitTest {
|
||||
@MockBean
|
||||
private SysUserSessionCoreService userSessionCoreService;
|
||||
@MockBean
|
||||
private SysSocialService socialService;
|
||||
private SysSocialCoreService socialService;
|
||||
@MockBean
|
||||
private SysPostService postService;
|
||||
|
||||
|
@ -101,12 +101,6 @@
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 三方云服务相关 -->
|
||||
<dependency>
|
||||
<groupId>com.xkcoding.justauth</groupId>
|
||||
<artifactId>justauth-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -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<SysSocialUserDO> {
|
||||
public interface SysSocialUserCoreMapper extends BaseMapperX<SysSocialUserDO> {
|
||||
|
||||
default List<SysSocialUserDO> selectListByTypeAndUnionId(Integer userType, Collection<Integer> types, String unionId) {
|
||||
return selectList(new QueryWrapper<SysSocialUserDO>().eq("user_type", userType)
|
@ -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 芋道源码
|
||||
*/
|
||||
|
@ -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<SysSocialUserDO> getAllSocialUserList(Integer type, String unionId, UserTypeEnum userTypeEnum);
|
||||
|
||||
@ -58,6 +58,7 @@ public interface SysSocialService {
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @return 社交用户列表
|
||||
* @param userTypeEnum 全局用户类型
|
||||
*/
|
||||
List<SysSocialUserDO> 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);
|
||||
|
||||
}
|
@ -2,10 +2,10 @@ 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;
|
||||
@ -38,7 +38,7 @@ 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;
|
||||
@ -47,7 +47,7 @@ public class SysSocialServiceImpl implements SysSocialService {
|
||||
private SysSocialAuthUserRedisDAO authSocialUserRedisDAO;
|
||||
|
||||
@Resource
|
||||
private SysSocialUserMapper socialUserMapper;
|
||||
private SysSocialUserCoreMapper socialUserMapper;
|
||||
|
||||
@Override
|
||||
public String getAuthorizeUrl(Integer type, String redirectUri) {
|
@ -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;
|
@ -8,3 +8,4 @@ DELETE FROM "sys_user_session";
|
||||
DELETE FROM "sys_dict_data";
|
||||
DELETE FROM "sys_sms_template";
|
||||
DELETE FROM "sys_sms_log";
|
||||
DELETE FROM "sys_social_user";
|
||||
|
@ -177,3 +177,23 @@ CREATE TABLE IF NOT EXISTS `sys_login_log` (
|
||||
"tenant_id" bigint not null default '0',
|
||||
PRIMARY KEY (`id`)
|
||||
) COMMENT ='系统访问记录';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "sys_social_user" (
|
||||
"id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"user_id" bigint NOT NULL,
|
||||
"user_type" tinyint NOT NULL DEFAULT '0',
|
||||
"type" tinyint NOT NULL,
|
||||
"openid" varchar(32) NOT NULL,
|
||||
"token" varchar(256) DEFAULT NULL,
|
||||
"union_id" varchar(32) NOT NULL,
|
||||
"raw_token_info" varchar(1024) NOT NULL,
|
||||
"nickname" varchar(32) NOT NULL,
|
||||
"avatar" varchar(255) DEFAULT NULL,
|
||||
"raw_user_info" varchar(1024) NOT NULL,
|
||||
"creator" varchar(64) DEFAULT '',
|
||||
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar(64) DEFAULT '',
|
||||
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '社交用户';
|
||||
|
50
yudao-framework/yudao-spring-boot-starter-biz-social/pom.xml
Normal file
50
yudao-framework/yudao-spring-boot-starter-biz-social/pom.xml
Normal file
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-framework</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<packaging>jar</packaging>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>yudao-spring-boot-starter-biz-social</artifactId>
|
||||
<name>${artifactId}</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-common</artifactId>
|
||||
</dependency>
|
||||
<!-- Spring 核心 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<!-- Web 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<!-- spring boot 配置所需依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- 三方云服务相关 -->
|
||||
<dependency>
|
||||
<groupId>com.xkcoding.justauth</groupId>
|
||||
<artifactId>justauth-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-redis</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
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.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 java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 第三方授权拓展 request 工厂类
|
||||
* 为使得拓展配置 {@link AuthConfig} 和默认配置齐平,所以自定义本工厂类
|
||||
*
|
||||
* @author timfruit
|
||||
* @date 2021-10-31
|
||||
*/
|
||||
// TODO @timfruit:单测
|
||||
public class YudaoAuthRequestFactory extends AuthRequestFactory {
|
||||
|
||||
protected JustAuthProperties properties;
|
||||
protected AuthStateCache authStateCache;
|
||||
|
||||
/**
|
||||
* 由于父类 configureHttpConfig 方法是 private 修饰,所以获取后,进行反射调用
|
||||
*/
|
||||
private final Method configureHttpConfigMethod = ReflectUtil.getMethod(AuthRequestFactory.class,
|
||||
"configureHttpConfig", String.class, AuthConfig.class, JustAuthProperties.JustAuthHttpConfig.class);
|
||||
|
||||
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
|
||||
ReflectUtil.invoke(this, configureHttpConfigMethod,
|
||||
authExtendSource.name(), config, properties.getHttpConfig());
|
||||
|
||||
// 获得拓展的 Request
|
||||
// noinspection SwitchStatementWithTooFewBranches
|
||||
switch (authExtendSource) {
|
||||
case WECHAT_MINI_PROGRAM:
|
||||
return new AuthWeChatMiniProgramRequest(config, authStateCache);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,13 +1,21 @@
|
||||
package cn.iocoder.yudao.coreservice.modules.system.compent.justauth;
|
||||
package cn.iocoder.yudao.framework.social.core.enums;
|
||||
|
||||
import me.zhyd.oauth.config.AuthSource;
|
||||
|
||||
/**
|
||||
* 拓展JustAuth各api需要的url, 用枚举类分平台类型管理
|
||||
*
|
||||
* 默认配置 {@link me.zhyd.oauth.config.AuthDefaultSource}
|
||||
*
|
||||
* @author timfruit
|
||||
*/
|
||||
public enum AuthExtendSource implements AuthSource {
|
||||
|
||||
/**
|
||||
* 微信小程序授权登录
|
||||
*/
|
||||
WECHAT_MINI_PROGRAM{
|
||||
WECHAT_MINI_PROGRAM {
|
||||
|
||||
@Override
|
||||
public String authorize() {
|
||||
// https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
|
||||
@ -28,6 +36,4 @@ public enum AuthExtendSource implements AuthSource {
|
||||
}
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
}
|
@ -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
|
||||
*/
|
||||
@ -15,7 +16,7 @@ import me.zhyd.oauth.model.AuthToken;
|
||||
public class AuthExtendToken extends AuthToken {
|
||||
|
||||
/**
|
||||
* 微信小程序 会话密钥
|
||||
* 微信小程序 - 会话密钥
|
||||
*/
|
||||
private String miniSessionKey;
|
||||
|
@ -1,6 +1,10 @@
|
||||
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 com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
import me.zhyd.oauth.cache.AuthStateCache;
|
||||
import me.zhyd.oauth.config.AuthConfig;
|
||||
import me.zhyd.oauth.exception.AuthException;
|
||||
@ -11,9 +15,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 +35,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.sessionKey);
|
||||
token.setOpenId(accessTokenObject.openid);
|
||||
token.setUnionId(accessTokenObject.unionid);
|
||||
return token;
|
||||
}
|
||||
|
||||
@ -64,10 +65,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 +87,14 @@ public class AuthWeChatMiniProgramRequest extends AuthDefaultRequest {
|
||||
.build();
|
||||
}
|
||||
|
||||
@Data
|
||||
private static class CodeSessionResponse {
|
||||
private int errcode;
|
||||
private String errmsg;
|
||||
@JsonProperty("session_key")
|
||||
private String sessionKey;
|
||||
private String openid;
|
||||
private String unionid;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
cn.iocoder.yudao.framework.social.config.YudaoSocialAutoConfiguration
|
@ -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.framework.security.core.annotations.PreAuthenticated;
|
||||
@ -38,7 +38,7 @@ public class SysAuthController {
|
||||
@Resource
|
||||
private SysSmsCodeService smsCodeService;
|
||||
@Resource
|
||||
private SysSocialService socialService;
|
||||
private SysSocialCoreService socialService;
|
||||
|
||||
@PostMapping("/login")
|
||||
@ApiOperation("使用手机 + 密码登录")
|
||||
@ -115,19 +115,6 @@ public class SysAuthController {
|
||||
return CommonResult.success(socialService.getAuthorizeUrl(type, redirectUri));
|
||||
}
|
||||
|
||||
// TODO @timfruit:这个接口,是要删除的么?
|
||||
@GetMapping("/social-login-get")
|
||||
@ApiOperation("微信公众号授权回调地址,输出social-login2的必要参数用于测试,使用 code 授权码")
|
||||
@ResponseBody
|
||||
@Deprecated
|
||||
public CommonResult<MbrAuthSocialLoginReqVO> socialLoginGet(HttpServletRequest request,String code,String state) {
|
||||
// 返回结果
|
||||
MbrAuthSocialLoginReqVO reqVO = MbrAuthSocialLoginReqVO.builder().state(state).code(code).build();
|
||||
reqVO.setType(12);
|
||||
//输出social-login2的必要参数用于测试
|
||||
System.out.println(JSON.toJSON(reqVO));
|
||||
return success(reqVO);
|
||||
}
|
||||
|
||||
@PostMapping("/social-login")
|
||||
@ApiOperation("社交登录,使用 code 授权码")
|
||||
@ -136,10 +123,9 @@ public class SysAuthController {
|
||||
return success(SysAuthLoginRespVO.builder().token(token).build());
|
||||
}
|
||||
|
||||
// TODO @timfruit:社交登陆时,使用手机验证码来验证哈。这块我当时没设计好,改改,嘿嘿。
|
||||
|
||||
@PostMapping("/social-login2")
|
||||
@ApiOperation("社交登录,使用 code 授权码 + 账号密码")
|
||||
@ApiOperation("社交登录,使用 手机号 + 手机验证码")
|
||||
public CommonResult<SysAuthLoginRespVO> socialLogin2(@RequestBody @Valid MbrAuthSocialLogin2ReqVO reqVO) {
|
||||
String token = authService.socialLogin2(reqVO, getClientIP(), getUserAgent());
|
||||
return success(SysAuthLoginRespVO.builder().token(token).build());
|
||||
|
@ -34,15 +34,16 @@ public class MbrAuthSocialLogin2ReqVO {
|
||||
@NotEmpty(message = "state 不能为空")
|
||||
private String state;
|
||||
|
||||
@ApiModelProperty(value = "账号", required = true, example = "yudaoyuanma")
|
||||
@NotEmpty(message = "登录账号不能为空")
|
||||
@Length(min = 4, max = 16, message = "账号长度为 4-16 位")
|
||||
@Pattern(regexp = "^[A-Za-z0-9]+$", message = "账号格式为数字以及字母")
|
||||
private String username;
|
||||
@ApiModelProperty(value = "手机号", required = true, example = "15119100000")
|
||||
@NotEmpty(message = "手机号不能为空")
|
||||
@Length(min = 11, max = 11, message = "手机号是11位数字")
|
||||
private String mobile;
|
||||
|
||||
@ApiModelProperty(value = "手机验证码", required = true, example = "1024")
|
||||
@NotEmpty(message = "手机验证码不能为空")
|
||||
@Length(min = 4, max = 6, message = "手机验证码长度为 4-6 位")
|
||||
@Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字")
|
||||
private String smsCode;
|
||||
|
||||
@ApiModelProperty(value = "密码", required = true, example = "buzhidao")
|
||||
@NotEmpty(message = "密码不能为空")
|
||||
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
|
||||
private String password;
|
||||
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ public interface SysAuthService extends SecurityAuthFrameworkService {
|
||||
String socialLogin(@Valid MbrAuthSocialLoginReqVO reqVO, String userIp, String userAgent);
|
||||
|
||||
/**
|
||||
* 社交登录,使用 code 授权码 + 账号密码
|
||||
* 社交登录,使用 手机号 + 手机验证码
|
||||
*
|
||||
* @param reqVO 登录信息
|
||||
* @param userIp 用户 IP
|
||||
|
@ -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;
|
||||
@ -57,6 +57,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;
|
||||
@ -70,7 +72,8 @@ public class SysAuthServiceImpl implements SysAuthService {
|
||||
@Resource
|
||||
private SysUserSessionCoreService userSessionCoreService;
|
||||
@Resource
|
||||
private SysSocialService socialService;
|
||||
private SysSocialCoreService socialService;
|
||||
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
@Resource
|
||||
@ -127,7 +130,7 @@ public class SysAuthServiceImpl implements SysAuthService {
|
||||
|
||||
// 如果未绑定 SysSocialUserDO 用户,则无法自动登录,进行报错
|
||||
String unionId = socialService.getAuthUserUnionId(authUser);
|
||||
List<SysSocialUserDO> socialUsers = socialService.getAllSocialUserList(reqVO.getType(), unionId, userTypeEnum);
|
||||
List<SysSocialUserDO> socialUsers = socialService.getAllSocialUserList(reqVO.getType(), unionId, USER_TYPE_ENUM);
|
||||
if (CollUtil.isEmpty(socialUsers)) {
|
||||
throw exception(AUTH_THIRD_LOGIN_NOT_BIND);
|
||||
}
|
||||
@ -143,7 +146,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);
|
||||
@ -151,19 +154,21 @@ public class SysAuthServiceImpl implements SysAuthService {
|
||||
|
||||
@Override
|
||||
public String socialLogin2(MbrAuthSocialLogin2ReqVO reqVO, String userIp, String userAgent) {
|
||||
// 使用 code 授权码,进行登录
|
||||
AuthUser authUser = socialService.getAuthUser(reqVO.getType(), reqVO.getCode(), reqVO.getState());
|
||||
org.springframework.util.Assert.notNull(authUser, "授权用户不为空");
|
||||
|
||||
// 使用账号密码,进行登录。
|
||||
LoginUser loginUser = this.login0(reqVO.getUsername(), reqVO.getPassword());
|
||||
// loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId())); // 获取用户角色列表
|
||||
// 使用手机号、手机验证码登录
|
||||
SysAuthSmsLoginReqVO loginReqVO = SysAuthSmsLoginReqVO
|
||||
.builder()
|
||||
.mobile(reqVO.getMobile())
|
||||
.code(reqVO.getSmsCode())
|
||||
.build();
|
||||
String sessionId = this.smsLogin(loginReqVO, userIp, userAgent);
|
||||
LoginUser loginUser = userSessionCoreService.getLoginUser(sessionId);
|
||||
|
||||
// 绑定社交用户(新增)
|
||||
socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, userTypeEnum);
|
||||
|
||||
// 缓存登录用户到 Redis 中,返回 sessionId 编号
|
||||
return userSessionCoreService.createUserSession(loginUser, userIp, userAgent);
|
||||
socialService.bindSocialUser(loginUser.getId(), reqVO.getType(), authUser, USER_TYPE_ENUM);
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -173,7 +178,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) {
|
||||
@ -347,7 +352,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(getClientIP());
|
||||
|
@ -150,24 +150,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::
|
||||
|
@ -170,17 +170,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::
|
||||
|
13
yudao-user-server/src/main/resources/static/READMD.md
Normal file
13
yudao-user-server/src/main/resources/static/READMD.md
Normal file
@ -0,0 +1,13 @@
|
||||
## 微信公众号
|
||||
|
||||
参考文章:https://www.yuque.com/docs/share/0e2966dd-89f8-4b69-980d-b876168725df
|
||||
|
||||
① 访问 social-login.html 选择【微信公众号】
|
||||
|
||||
② 微信公众号授权完成后,跳转回 social-login2.html,输入手机号 + 密码,进行绑定
|
||||
|
||||
## 微信小程序
|
||||
|
||||
参考文章:https://www.yuque.com/docs/share/88e3d30a-6830-45fc-8c25-dae485aef3aa
|
||||
|
||||
① 暂时使用 mini-program-test 项目
|
@ -13,14 +13,16 @@
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
let server = 'http://127.0.0.1:28080';
|
||||
// let server = 'http://127.0.0.1:28080';
|
||||
let server = 'http://192.168.1.2:28080';
|
||||
|
||||
|
||||
// 微信公众号
|
||||
$( "#wx_pub").on( "click", function() {
|
||||
// 获得授权链接
|
||||
$.ajax({
|
||||
url: server + "/api/social-auth-redirect?type=31&redirectUri=" +
|
||||
encodeURIComponent(server + '/api/social-login-get'),
|
||||
encodeURIComponent(server + '/static/social-login2.html'), //重定向地址
|
||||
method: 'GET',
|
||||
success: function( result ) {
|
||||
if (result.code !== 0) {
|
||||
|
@ -0,0 +1,87 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"/>
|
||||
<title>社交登陆测试页</title>
|
||||
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div>点击如下按钮,授权登录</div>
|
||||
<div>
|
||||
手机号<input id="mobile" value="15601691300"><br>
|
||||
手机验证码<input id="smsCode">
|
||||
<button id="send_sms_code">发送手机验证码</button>
|
||||
<br>
|
||||
<button id="wx_pub">微信公众号授权登录</button>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
// let server = 'http://127.0.0.1:28080';
|
||||
let server = 'http://192.168.1.2:28080';
|
||||
|
||||
let type = 31; //登录类型 微信公众号
|
||||
|
||||
// 微信公众号
|
||||
$("#wx_pub").on("click", function () {
|
||||
let code = getUrlParam("code"); // 访问授权连接后,会回调本页面地址,参数在本页面url后面
|
||||
let state = getUrlParam("state");
|
||||
console.log("获取code: " + code + ", state: " + state)
|
||||
|
||||
let data = {
|
||||
'mobile': $('#mobile').val(),
|
||||
'smsCode': $('#smsCode').val(),
|
||||
'code': code,
|
||||
'state': state,
|
||||
'type': type
|
||||
}
|
||||
|
||||
// 调用授权登录接口
|
||||
$.ajax({
|
||||
url: server + "/api/social-login2",
|
||||
method: 'POST',
|
||||
data: JSON.stringify(data),
|
||||
contentType: "application/json;charset=utf-8",
|
||||
dataType: "json",
|
||||
success: function( result ) {
|
||||
if (result.code !== 0) {
|
||||
alert('调用授权登录接口失败,原因:' + result.msg)
|
||||
return;
|
||||
}
|
||||
alert("授权登录成功, token: "+result.data.token)
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// 发送手机验证码
|
||||
$("#send_sms_code").on("click", function () {
|
||||
let data = {
|
||||
'mobile': $('#mobile').val(),
|
||||
'scene': 1 // 手机号登陆 类型
|
||||
}
|
||||
$.ajax({
|
||||
url: server + "/api/send-sms-code",
|
||||
method: 'POST',
|
||||
data: JSON.stringify(data),
|
||||
contentType: "application/json;charset=utf-8",
|
||||
dataType: "json",
|
||||
success: function (result) {
|
||||
if (result.code !== 0) {
|
||||
alert('发送手机验证码失败,原因:' + result.msg)
|
||||
return;
|
||||
}
|
||||
alert("发送成功, 请查看日志");
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
//获取url中的参数
|
||||
function getUrlParam(name) {
|
||||
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
|
||||
var r = window.location.search.substr(1).match(reg); //匹配目标参数
|
||||
if (r != null) return unescape(r[2]);
|
||||
return null; //返回参数值
|
||||
}
|
||||
</script>
|
||||
</html>
|
@ -4,6 +4,7 @@ import cn.iocoder.yudao.userserver.modules.member.controller.user.SysUserProfile
|
||||
import cn.iocoder.yudao.userserver.modules.member.service.user.MbrUserService;
|
||||
import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
@ -46,6 +47,7 @@ public class SysUserProfileControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testUpdateMobile_success() throws Exception {
|
||||
//模拟接口调用
|
||||
this.mockMvc.perform(post("/system/user/profile/update-mobile")
|
||||
|
@ -1,6 +1,6 @@
|
||||
package cn.iocoder.yudao.userserver.modules.system.controller;
|
||||
|
||||
import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialService;
|
||||
import cn.iocoder.yudao.coreservice.modules.system.service.social.SysSocialCoreService;
|
||||
import cn.iocoder.yudao.userserver.modules.system.controller.auth.SysAuthController;
|
||||
import cn.iocoder.yudao.userserver.modules.system.service.auth.SysAuthService;
|
||||
import cn.iocoder.yudao.userserver.modules.system.service.sms.SysSmsCodeService;
|
||||
@ -14,9 +14,7 @@ import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.springframework.http.HttpHeaders.AUTHORIZATION;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
@ -36,8 +34,7 @@ public class SysAuthControllerTest {
|
||||
@Mock
|
||||
private SysSmsCodeService smsCodeService;
|
||||
@Mock
|
||||
private SysSocialService socialService;
|
||||
|
||||
private SysSocialCoreService socialService;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
@ -50,26 +47,22 @@ public class SysAuthControllerTest {
|
||||
|
||||
@Test
|
||||
public void testResetPassword_success() throws Exception {
|
||||
//模拟接口调用
|
||||
// 模拟接口调用
|
||||
this.mockMvc.perform(post("/reset-password")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("{\"password\":\"1123\",\"code\":\"123456\"}}"))
|
||||
.andExpect(status().isOk())
|
||||
.andDo(MockMvcResultHandlers.print());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdatePassword_success() throws Exception {
|
||||
//模拟接口调用
|
||||
// 模拟接口调用
|
||||
this.mockMvc.perform(post("/update-password")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("{\"password\":\"1123\",\"code\":\"123456\",\"oldPassword\":\"1123\"}}"))
|
||||
.andExpect(status().isOk())
|
||||
.andDo(MockMvcResultHandlers.print());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package cn.iocoder.yudao.userserver.modules.system.service;
|
||||
import cn.iocoder.yudao.coreservice.modules.member.dal.dataobject.user.MbrUserDO;
|
||||
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.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
|
||||
import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
|
||||
@ -53,7 +53,7 @@ public class SysAuthServiceTest extends BaseDbAndRedisUnitTest {
|
||||
@MockBean
|
||||
private SysUserSessionCoreService userSessionCoreService;
|
||||
@MockBean
|
||||
private SysSocialService socialService;
|
||||
private SysSocialCoreService socialService;
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
@MockBean
|
||||
|
@ -14,6 +14,7 @@ CREATE TABLE IF NOT EXISTS "mbr_user" (
|
||||
"updater" varchar(64) NULL DEFAULT '' COMMENT '更新者',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
"deleted" bit(1) NOT NULL DEFAULT '0' COMMENT '是否删除',
|
||||
"tenant_id" bigint not null default '0',
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '会员表';
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user