Browse Source

用户 app 的社交登录接口,合并到手机号 + 密码,手机号 + 验证码的 login 接口中,统一维护。

YunaiV 2 years ago
parent
commit
1b7093f5c1

+ 1 - 1
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}
  *

+ 3 - 9
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<AppAuthLoginRespVO> socialQuickLogin(@RequestBody @Valid AppAuthSocialQuickLoginReqVO reqVO) {
-        return success(authService.socialQuickLogin(reqVO));
-    }
-
-    @PostMapping("/social-bind-login")
-    @ApiOperation(value = "社交绑定登录,使用 手机号 + 手机验证码", notes = "适合未登录的用户,进行登录 + 绑定")
-    public CommonResult<AppAuthLoginRespVO> socialBindLogin(@RequestBody @Valid AppAuthSocialBindLoginReqVO reqVO) {
-        return success(authService.socialBindLogin(reqVO));
+    public CommonResult<AppAuthLoginRespVO> socialLogin(@RequestBody @Valid AppAuthSocialLoginReqVO reqVO) {
+        return success(authService.socialLogin(reqVO));
     }
 
 }

+ 27 - 1
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);
+    }
+
 }

+ 27 - 1
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);
+    }
+
 }

+ 0 - 48
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialBindLoginReqVO.java

@@ -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;
-
-}

+ 1 - 1
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthSocialQuickLoginReqVO.java → 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)

+ 1 - 2
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);

+ 1 - 9
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

+ 14 - 13
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);

+ 4 - 0
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 {
 
     /**