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

This commit is contained in:
YunaiV 2022-05-29 22:03:46 +08:00
parent 75d34080df
commit 1b7093f5c1
10 changed files with 79 additions and 85 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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)

View File

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

View File

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

View File

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

View File

@ -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 {
/**