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 ce61bca40..3cd62b540 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 @@ -3,7 +3,7 @@ package cn.iocoder.yudao.framework.social.core.enums; import me.zhyd.oauth.config.AuthSource; /** - * 拓展JustAuth各api需要的url, 用枚举类分平台类型管理 + * 拓展 JustAuth 各 api 需要的 url, 用枚举类分平台类型管理 * * 默认配置 {@link me.zhyd.oauth.config.AuthDefaultSource} * diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java index 6532f7aca..8a7091c02 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java @@ -104,16 +104,10 @@ public class AppAuthController { return CommonResult.success(authService.getSocialAuthorizeUrl(type, redirectUri)); } - @PostMapping("/social-quick-login") + @PostMapping("/social-login") @ApiOperation(value = "社交快捷登录,使用 code 授权码", notes = "适合未登录的用户,但是社交账号已绑定用户") - public CommonResult socialQuickLogin(@RequestBody @Valid AppAuthSocialQuickLoginReqVO reqVO) { - return success(authService.socialQuickLogin(reqVO)); - } - - @PostMapping("/social-bind-login") - @ApiOperation(value = "社交绑定登录,使用 手机号 + 手机验证码", notes = "适合未登录的用户,进行登录 + 绑定") - public CommonResult socialBindLogin(@RequestBody @Valid AppAuthSocialBindLoginReqVO reqVO) { - return success(authService.socialBindLogin(reqVO)); + public CommonResult socialLogin(@RequestBody @Valid AppAuthSocialLoginReqVO reqVO) { + return success(authService.socialLogin(reqVO)); } } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginReqVO.java index 1055e979b..d8fe3940f 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginReqVO.java @@ -1,6 +1,9 @@ package cn.iocoder.yudao.module.member.controller.app.auth.vo; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.framework.common.validation.Mobile; +import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; @@ -9,9 +12,10 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.hibernate.validator.constraints.Length; +import javax.validation.constraints.AssertTrue; import javax.validation.constraints.NotEmpty; -@ApiModel("用户 APP - 手机 + 密码登录 Request VO") +@ApiModel(value = "用户 APP - 手机 + 密码登录 Request VO", description = "如果登录并绑定社交用户,需要传递 social 开头的参数") @Data @NoArgsConstructor @AllArgsConstructor @@ -28,4 +32,26 @@ public class AppAuthLoginReqVO { @Length(min = 4, max = 16, message = "密码长度为 4-16 位") private String password; + // ========== 绑定社交登录时,需要传递如下参数 ========== + + @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") + @InEnum(SocialTypeEnum.class) + private Integer socialType; + + @ApiModelProperty(value = "授权码", required = true, example = "1024") + private String socialCode; + + @ApiModelProperty(value = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") + private String socialState; + + @AssertTrue(message = "授权码不能为空") + public boolean isSocialCodeValid() { + return socialType == null || StrUtil.isNotEmpty(socialCode); + } + + @AssertTrue(message = "授权 state 不能为空") + public boolean isSocialState() { + return socialType == null || StrUtil.isNotEmpty(socialState); + } + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsLoginReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsLoginReqVO.java index 063caf80d..dd6de5d59 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsLoginReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSmsLoginReqVO.java @@ -1,6 +1,9 @@ package cn.iocoder.yudao.module.member.controller.app.auth.vo; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.framework.common.validation.Mobile; +import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; @@ -9,10 +12,11 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.hibernate.validator.constraints.Length; +import javax.validation.constraints.AssertTrue; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; -@ApiModel("用户 APP - 手机 + 验证码登录 Request VO") +@ApiModel(value = "用户 APP - 手机 + 验证码登录 Request VO", description = "如果登录并绑定社交用户,需要传递 social 开头的参数") @Data @NoArgsConstructor @AllArgsConstructor @@ -30,4 +34,26 @@ public class AppAuthSmsLoginReqVO { @Pattern(regexp = "^[0-9]+$", message = "手机验证码必须都是数字") private String code; + // ========== 绑定社交登录时,需要传递如下参数 ========== + + @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") + @InEnum(SocialTypeEnum.class) + private Integer socialType; + + @ApiModelProperty(value = "授权码", required = true, example = "1024") + private String socialCode; + + @ApiModelProperty(value = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") + private String socialState; + + @AssertTrue(message = "授权码不能为空") + public boolean isSocialCodeValid() { + return socialType == null || StrUtil.isNotEmpty(socialCode); + } + + @AssertTrue(message = "授权 state 不能为空") + public boolean isSocialState() { + return socialType == null || StrUtil.isNotEmpty(socialState); + } + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialBindLoginReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialBindLoginReqVO.java deleted file mode 100644 index e5c173768..000000000 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialBindLoginReqVO.java +++ /dev/null @@ -1,48 +0,0 @@ -package cn.iocoder.yudao.module.member.controller.app.auth.vo; - -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; -import org.hibernate.validator.constraints.Length; - -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Pattern; - -@ApiModel("用户 APP - 社交绑定登录 Request VO,使用 code 授权码 + 账号密码") -@Data -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class AppAuthSocialBindLoginReqVO { - - @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") - @InEnum(SocialTypeEnum.class) - @NotNull(message = "社交平台的类型不能为空") - private Integer type; - - @ApiModelProperty(value = "授权码", required = true, example = "1024") - @NotEmpty(message = "授权码不能为空") - private String code; - - @ApiModelProperty(value = "state", required = true, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") - @NotEmpty(message = "state 不能为空") - private String state; - - @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; - -} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialQuickLoginReqVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLoginReqVO.java similarity index 96% rename from yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialQuickLoginReqVO.java rename to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLoginReqVO.java index 02c26bcb3..7a5856d67 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialQuickLoginReqVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialLoginReqVO.java @@ -17,7 +17,7 @@ import javax.validation.constraints.NotNull; @NoArgsConstructor @AllArgsConstructor @Builder -public class AppAuthSocialQuickLoginReqVO { +public class AppAuthSocialLoginReqVO { @ApiModelProperty(value = "社交平台的类型", required = true, example = "10", notes = "参见 SysUserSocialTypeEnum 枚举值") @InEnum(SocialTypeEnum.class) diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java index 5a44d76bd..73577cf6b 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java @@ -16,8 +16,7 @@ public interface AuthConvert { AuthConvert INSTANCE = Mappers.getMapper(AuthConvert.class); - SocialUserBindReqDTO convert(Long userId, Integer userType, AppAuthSocialBindLoginReqVO reqVO); - SocialUserBindReqDTO convert(Long userId, Integer userType, AppAuthSocialQuickLoginReqVO reqVO); + SocialUserBindReqDTO convert(Long userId, Integer userType, AppAuthSocialLoginReqVO reqVO); SocialUserUnbindReqDTO convert(Long userId, Integer userType, AppSocialUserUnbindReqVO reqVO); SmsCodeSendReqDTO convert(AppAuthSmsSendReqVO reqVO); diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthService.java index ded192217..de8132de0 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthService.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthService.java @@ -42,15 +42,7 @@ public interface MemberAuthService { * @param reqVO 登录信息 * @return 登录结果 */ - AppAuthLoginRespVO socialQuickLogin(@Valid AppAuthSocialQuickLoginReqVO reqVO); - - /** - * 社交登录,使用 手机号 + 手机验证码 - * - * @param reqVO 登录信息 - * @return 登录结果 - */ - AppAuthLoginRespVO socialBindLogin(@Valid AppAuthSocialBindLoginReqVO reqVO); + AppAuthLoginRespVO socialLogin(@Valid AppAuthSocialLoginReqVO reqVO); /** * 获得社交认证 URL diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java index 5911d81c3..dce13f28f 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java @@ -18,6 +18,7 @@ import cn.iocoder.yudao.module.system.api.logger.LoginLogApi; import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO; import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; import cn.iocoder.yudao.module.system.api.social.SocialUserApi; +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; import cn.iocoder.yudao.module.system.enums.auth.OAuth2ClientConstants; import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum; import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum; @@ -65,6 +66,12 @@ public class MemberAuthServiceImpl implements MemberAuthService { // 使用手机 + 密码,进行登录。 MemberUserDO user = login0(reqVO.getMobile(), reqVO.getPassword()); + // 如果 socialType 非空,说明需要绑定社交用户 + if (reqVO.getSocialType() != null) { + socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), + reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); + } + // 创建 Token 令牌,记录登录日志 return createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_MOBILE); } @@ -80,12 +87,18 @@ public class MemberAuthServiceImpl implements MemberAuthService { MemberUserDO user = userService.createUserIfAbsent(reqVO.getMobile(), userIp); Assert.notNull(user, "获取用户失败,结果为空"); + // 如果 socialType 非空,说明需要绑定社交用户 + if (reqVO.getSocialType() != null) { + socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), + reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); + } + // 创建 Token 令牌,记录登录日志 return createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_SMS); } @Override - public AppAuthLoginRespVO socialQuickLogin(AppAuthSocialQuickLoginReqVO reqVO) { + public AppAuthLoginRespVO socialLogin(AppAuthSocialLoginReqVO reqVO) { // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号 Long userId = socialUserApi.getBindUserId(UserTypeEnum.MEMBER.getValue(), reqVO.getType(), reqVO.getCode(), reqVO.getState()); @@ -103,18 +116,6 @@ public class MemberAuthServiceImpl implements MemberAuthService { return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL); } - @Override - public AppAuthLoginRespVO socialBindLogin(AppAuthSocialBindLoginReqVO reqVO) { - // 使用手机号、手机验证码登录 - AppAuthSmsLoginReqVO loginReqVO = AppAuthSmsLoginReqVO.builder() - .mobile(reqVO.getMobile()).code(reqVO.getSmsCode()).build(); - AppAuthLoginRespVO token = smsLogin(loginReqVO); - - // 绑定社交用户 - socialUserApi.bindSocialUser(AuthConvert.INSTANCE.convert(token.getUserId(), getUserType().getValue(), reqVO)); - return token; - } - private AppAuthLoginRespVO createTokenAfterLoginSuccess(MemberUserDO user, String mobile, LoginLogTypeEnum logType) { // 插入登陆日志 createLoginLog(user.getId(), mobile, logType, LoginResultEnum.SUCCESS); diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialUserBindReqDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialUserBindReqDTO.java index ccc1c62ae..a3bb6b315 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialUserBindReqDTO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialUserBindReqDTO.java @@ -3,7 +3,9 @@ package cn.iocoder.yudao.module.system.api.social.dto; import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; @@ -14,6 +16,8 @@ import javax.validation.constraints.NotNull; * @author 芋道源码 */ @Data +@NoArgsConstructor +@AllArgsConstructor public class SocialUserBindReqDTO { /**