Commit 40e1a879e3b38d830b25f81716986d485f115d61
1 parent
4265441e
登录:社交登录时,额外返回 openid
Showing
13 changed files
with
111 additions
and
46 deletions
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http
| @@ -28,6 +28,17 @@ tenant-id: {{appTenentId}} | @@ -28,6 +28,17 @@ tenant-id: {{appTenentId}} | ||
| 28 | "code": 9999 | 28 | "code": 9999 |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | +### 请求 /social-login 接口 => 成功 | ||
| 32 | +POST {{appApi}}/member/auth/social-login | ||
| 33 | +Content-Type: application/json | ||
| 34 | +tenant-id: {{appTenentId}} | ||
| 35 | + | ||
| 36 | +{ | ||
| 37 | + "type": 34, | ||
| 38 | + "code": "0e1oc9000CTjFQ1oim200bhtb61oc90g", | ||
| 39 | + "state": "default" | ||
| 40 | +} | ||
| 41 | + | ||
| 31 | ### 请求 /weixin-mini-app-login 接口 => 成功 | 42 | ### 请求 /weixin-mini-app-login 接口 => 成功 |
| 32 | POST {{appApi}}/member/auth/weixin-mini-app-login | 43 | POST {{appApi}}/member/auth/weixin-mini-app-login |
| 33 | Content-Type: application/json | 44 | Content-Type: application/json |
| @@ -38,7 +49,6 @@ tenant-id: {{appTenentId}} | @@ -38,7 +49,6 @@ tenant-id: {{appTenentId}} | ||
| 38 | "loginCode": "001frTkl21JUf94VGxol2hSlff1frTkR" | 49 | "loginCode": "001frTkl21JUf94VGxol2hSlff1frTkR" |
| 39 | } | 50 | } |
| 40 | 51 | ||
| 41 | - | ||
| 42 | ### 请求 /logout 接口 => 成功 | 52 | ### 请求 /logout 接口 => 成功 |
| 43 | POST {{appApi}}/member/auth/logout | 53 | POST {{appApi}}/member/auth/logout |
| 44 | Content-Type: application/json | 54 | Content-Type: application/json |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java
| @@ -27,4 +27,12 @@ public class AppAuthLoginRespVO { | @@ -27,4 +27,12 @@ public class AppAuthLoginRespVO { | ||
| 27 | @Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED) | 27 | @Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| 28 | private LocalDateTime expiresTime; | 28 | private LocalDateTime expiresTime; |
| 29 | 29 | ||
| 30 | + /** | ||
| 31 | + * 仅社交登录、社交绑定时会返回 | ||
| 32 | + * | ||
| 33 | + * 为什么需要返回?微信公众号、微信小程序支付需要传递 openid 给支付接口 | ||
| 34 | + */ | ||
| 35 | + @Schema(description = "社交用户 openid", example = "qq768") | ||
| 36 | + private String openid; | ||
| 37 | + | ||
| 30 | } | 38 | } |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java
| @@ -25,7 +25,7 @@ public interface AuthConvert { | @@ -25,7 +25,7 @@ public interface AuthConvert { | ||
| 25 | SmsCodeUseReqDTO convert(AppMemberUserResetPasswordReqVO reqVO, SmsSceneEnum scene, String usedIp); | 25 | SmsCodeUseReqDTO convert(AppMemberUserResetPasswordReqVO reqVO, SmsSceneEnum scene, String usedIp); |
| 26 | SmsCodeUseReqDTO convert(AppAuthSmsLoginReqVO reqVO, Integer scene, String usedIp); | 26 | SmsCodeUseReqDTO convert(AppAuthSmsLoginReqVO reqVO, Integer scene, String usedIp); |
| 27 | 27 | ||
| 28 | - AppAuthLoginRespVO convert(OAuth2AccessTokenRespDTO bean); | 28 | + AppAuthLoginRespVO convert(OAuth2AccessTokenRespDTO bean, String openid); |
| 29 | 29 | ||
| 30 | SmsCodeValidateReqDTO convert(AppAuthSmsValidateReqVO bean); | 30 | SmsCodeValidateReqDTO convert(AppAuthSmsValidateReqVO bean); |
| 31 | 31 |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java
| @@ -20,6 +20,7 @@ import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenRespDTO; | @@ -20,6 +20,7 @@ import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenRespDTO; | ||
| 20 | import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; | 20 | import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; |
| 21 | import cn.iocoder.yudao.module.system.api.social.SocialUserApi; | 21 | import cn.iocoder.yudao.module.system.api.social.SocialUserApi; |
| 22 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; | 22 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 23 | +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; | ||
| 23 | import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum; | 24 | import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum; |
| 24 | import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum; | 25 | import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum; |
| 25 | import cn.iocoder.yudao.module.system.enums.oauth2.OAuth2ClientConstants; | 26 | import cn.iocoder.yudao.module.system.enums.oauth2.OAuth2ClientConstants; |
| @@ -65,13 +66,14 @@ public class MemberAuthServiceImpl implements MemberAuthService { | @@ -65,13 +66,14 @@ public class MemberAuthServiceImpl implements MemberAuthService { | ||
| 65 | MemberUserDO user = login0(reqVO.getMobile(), reqVO.getPassword()); | 66 | MemberUserDO user = login0(reqVO.getMobile(), reqVO.getPassword()); |
| 66 | 67 | ||
| 67 | // 如果 socialType 非空,说明需要绑定社交用户 | 68 | // 如果 socialType 非空,说明需要绑定社交用户 |
| 69 | + String openid = null; | ||
| 68 | if (reqVO.getSocialType() != null) { | 70 | if (reqVO.getSocialType() != null) { |
| 69 | - socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), | 71 | + openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), |
| 70 | reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); | 72 | reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); |
| 71 | } | 73 | } |
| 72 | 74 | ||
| 73 | // 创建 Token 令牌,记录登录日志 | 75 | // 创建 Token 令牌,记录登录日志 |
| 74 | - return createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_MOBILE); | 76 | + return createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_MOBILE, openid); |
| 75 | } | 77 | } |
| 76 | 78 | ||
| 77 | @Override | 79 | @Override |
| @@ -86,32 +88,33 @@ public class MemberAuthServiceImpl implements MemberAuthService { | @@ -86,32 +88,33 @@ public class MemberAuthServiceImpl implements MemberAuthService { | ||
| 86 | Assert.notNull(user, "获取用户失败,结果为空"); | 88 | Assert.notNull(user, "获取用户失败,结果为空"); |
| 87 | 89 | ||
| 88 | // 如果 socialType 非空,说明需要绑定社交用户 | 90 | // 如果 socialType 非空,说明需要绑定社交用户 |
| 91 | + String openid = null; | ||
| 89 | if (reqVO.getSocialType() != null) { | 92 | if (reqVO.getSocialType() != null) { |
| 90 | - socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), | 93 | + openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), |
| 91 | reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); | 94 | reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); |
| 92 | } | 95 | } |
| 93 | 96 | ||
| 94 | // 创建 Token 令牌,记录登录日志 | 97 | // 创建 Token 令牌,记录登录日志 |
| 95 | - return createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_SMS); | 98 | + return createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_SMS, openid); |
| 96 | } | 99 | } |
| 97 | 100 | ||
| 98 | @Override | 101 | @Override |
| 99 | public AppAuthLoginRespVO socialLogin(AppAuthSocialLoginReqVO reqVO) { | 102 | public AppAuthLoginRespVO socialLogin(AppAuthSocialLoginReqVO reqVO) { |
| 100 | // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号 | 103 | // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号 |
| 101 | - Long userId = socialUserApi.getBindUserId(UserTypeEnum.MEMBER.getValue(), reqVO.getType(), | 104 | + SocialUserRespDTO socialUser = socialUserApi.getSocialUser(UserTypeEnum.MEMBER.getValue(), reqVO.getType(), |
| 102 | reqVO.getCode(), reqVO.getState()); | 105 | reqVO.getCode(), reqVO.getState()); |
| 103 | - if (userId == null) { | 106 | + if (socialUser == null) { |
| 104 | throw exception(AUTH_THIRD_LOGIN_NOT_BIND); | 107 | throw exception(AUTH_THIRD_LOGIN_NOT_BIND); |
| 105 | } | 108 | } |
| 106 | 109 | ||
| 107 | // 自动登录 | 110 | // 自动登录 |
| 108 | - MemberUserDO user = userService.getUser(userId); | 111 | + MemberUserDO user = userService.getUser(socialUser.getUserId()); |
| 109 | if (user == null) { | 112 | if (user == null) { |
| 110 | throw exception(USER_NOT_EXISTS); | 113 | throw exception(USER_NOT_EXISTS); |
| 111 | } | 114 | } |
| 112 | 115 | ||
| 113 | // 创建 Token 令牌,记录登录日志 | 116 | // 创建 Token 令牌,记录登录日志 |
| 114 | - return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL); | 117 | + return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL, socialUser.getOpenid()); |
| 115 | } | 118 | } |
| 116 | 119 | ||
| 117 | @Override | 120 | @Override |
| @@ -129,14 +132,15 @@ public class MemberAuthServiceImpl implements MemberAuthService { | @@ -129,14 +132,15 @@ public class MemberAuthServiceImpl implements MemberAuthService { | ||
| 129 | Assert.notNull(user, "获取用户失败,结果为空"); | 132 | Assert.notNull(user, "获取用户失败,结果为空"); |
| 130 | 133 | ||
| 131 | // 绑定社交用户 | 134 | // 绑定社交用户 |
| 132 | - socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), | 135 | + String openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), |
| 133 | SocialTypeEnum.WECHAT_MINI_APP.getType(), reqVO.getLoginCode(), "")); | 136 | SocialTypeEnum.WECHAT_MINI_APP.getType(), reqVO.getLoginCode(), "")); |
| 134 | 137 | ||
| 135 | // 创建 Token 令牌,记录登录日志 | 138 | // 创建 Token 令牌,记录登录日志 |
| 136 | - return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL); | 139 | + return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL, openid); |
| 137 | } | 140 | } |
| 138 | 141 | ||
| 139 | - private AppAuthLoginRespVO createTokenAfterLoginSuccess(MemberUserDO user, String mobile, LoginLogTypeEnum logType) { | 142 | + private AppAuthLoginRespVO createTokenAfterLoginSuccess(MemberUserDO user, String mobile, |
| 143 | + LoginLogTypeEnum logType, String openid) { | ||
| 140 | // 插入登陆日志 | 144 | // 插入登陆日志 |
| 141 | createLoginLog(user.getId(), mobile, logType, LoginResultEnum.SUCCESS); | 145 | createLoginLog(user.getId(), mobile, logType, LoginResultEnum.SUCCESS); |
| 142 | // 创建 Token 令牌 | 146 | // 创建 Token 令牌 |
| @@ -144,7 +148,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { | @@ -144,7 +148,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { | ||
| 144 | .setUserId(user.getId()).setUserType(getUserType().getValue()) | 148 | .setUserId(user.getId()).setUserType(getUserType().getValue()) |
| 145 | .setClientId(OAuth2ClientConstants.CLIENT_ID_DEFAULT)); | 149 | .setClientId(OAuth2ClientConstants.CLIENT_ID_DEFAULT)); |
| 146 | // 构建返回结果 | 150 | // 构建返回结果 |
| 147 | - return AuthConvert.INSTANCE.convert(accessTokenRespDTO); | 151 | + return AuthConvert.INSTANCE.convert(accessTokenRespDTO, openid); |
| 148 | } | 152 | } |
| 149 | 153 | ||
| 150 | @Override | 154 | @Override |
| @@ -231,7 +235,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { | @@ -231,7 +235,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { | ||
| 231 | public AppAuthLoginRespVO refreshToken(String refreshToken) { | 235 | public AppAuthLoginRespVO refreshToken(String refreshToken) { |
| 232 | OAuth2AccessTokenRespDTO accessTokenDO = oauth2TokenApi.refreshAccessToken(refreshToken, | 236 | OAuth2AccessTokenRespDTO accessTokenDO = oauth2TokenApi.refreshAccessToken(refreshToken, |
| 233 | OAuth2ClientConstants.CLIENT_ID_DEFAULT); | 237 | OAuth2ClientConstants.CLIENT_ID_DEFAULT); |
| 234 | - return AuthConvert.INSTANCE.convert(accessTokenDO); | 238 | + return AuthConvert.INSTANCE.convert(accessTokenDO, null); |
| 235 | } | 239 | } |
| 236 | 240 | ||
| 237 | private void createLogoutLog(Long userId) { | 241 | private void createLogoutLog(Long userId) { |
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApi.java
| @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.api.social; | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.api.social; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.exception.ServiceException; | 3 | import cn.iocoder.yudao.framework.common.exception.ServiceException; |
| 4 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; | 4 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 5 | +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; | ||
| 5 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO; | 6 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO; |
| 6 | import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; | 7 | import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; |
| 7 | 8 | ||
| @@ -27,8 +28,9 @@ public interface SocialUserApi { | @@ -27,8 +28,9 @@ public interface SocialUserApi { | ||
| 27 | * 绑定社交用户 | 28 | * 绑定社交用户 |
| 28 | * | 29 | * |
| 29 | * @param reqDTO 绑定信息 | 30 | * @param reqDTO 绑定信息 |
| 31 | + * @return 社交用户 openid | ||
| 30 | */ | 32 | */ |
| 31 | - void bindSocialUser(@Valid SocialUserBindReqDTO reqDTO); | 33 | + String bindSocialUser(@Valid SocialUserBindReqDTO reqDTO); |
| 32 | 34 | ||
| 33 | /** | 35 | /** |
| 34 | * 取消绑定社交用户 | 36 | * 取消绑定社交用户 |
| @@ -38,16 +40,17 @@ public interface SocialUserApi { | @@ -38,16 +40,17 @@ public interface SocialUserApi { | ||
| 38 | void unbindSocialUser(@Valid SocialUserUnbindReqDTO reqDTO); | 40 | void unbindSocialUser(@Valid SocialUserUnbindReqDTO reqDTO); |
| 39 | 41 | ||
| 40 | /** | 42 | /** |
| 41 | - * 获得社交用户的绑定用户编号 | ||
| 42 | - * 注意,返回的是 MemberUser 或者 AdminUser 的 id 编号! | 43 | + * 获得社交用户 |
| 44 | + * | ||
| 43 | * 在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常 | 45 | * 在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常 |
| 44 | * | 46 | * |
| 45 | * @param userType 用户类型 | 47 | * @param userType 用户类型 |
| 46 | * @param type 社交平台的类型 | 48 | * @param type 社交平台的类型 |
| 47 | * @param code 授权码 | 49 | * @param code 授权码 |
| 48 | * @param state state | 50 | * @param state state |
| 49 | - * @return 绑定用户编号 | 51 | + * @return 社交用户 |
| 50 | */ | 52 | */ |
| 51 | - Long getBindUserId(Integer userType, Integer type, String code, String state); | 53 | + SocialUserRespDTO getSocialUser(Integer userType, Integer type, |
| 54 | + String code, String state); | ||
| 52 | 55 | ||
| 53 | } | 56 | } |
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialUserRespDTO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.system.api.social.dto; | ||
| 2 | + | ||
| 3 | +import lombok.AllArgsConstructor; | ||
| 4 | +import lombok.Data; | ||
| 5 | +import lombok.NoArgsConstructor; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * 社交用户 Response DTO | ||
| 9 | + * | ||
| 10 | + * @author 芋道源码 | ||
| 11 | + */ | ||
| 12 | +@Data | ||
| 13 | +@NoArgsConstructor | ||
| 14 | +@AllArgsConstructor | ||
| 15 | +public class SocialUserRespDTO { | ||
| 16 | + | ||
| 17 | + /** | ||
| 18 | + * 社交用户 openid | ||
| 19 | + */ | ||
| 20 | + private String openid; | ||
| 21 | + | ||
| 22 | + /** | ||
| 23 | + * 关联的用户编号 | ||
| 24 | + */ | ||
| 25 | + private Long userId; | ||
| 26 | + | ||
| 27 | +} |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApiImpl.java
| 1 | package cn.iocoder.yudao.module.system.api.social; | 1 | package cn.iocoder.yudao.module.system.api.social; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; | 3 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 4 | +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; | ||
| 4 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO; | 5 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO; |
| 5 | import cn.iocoder.yudao.module.system.service.social.SocialUserService; | 6 | import cn.iocoder.yudao.module.system.service.social.SocialUserService; |
| 6 | import org.springframework.stereotype.Service; | 7 | import org.springframework.stereotype.Service; |
| @@ -26,8 +27,8 @@ public class SocialUserApiImpl implements SocialUserApi { | @@ -26,8 +27,8 @@ public class SocialUserApiImpl implements SocialUserApi { | ||
| 26 | } | 27 | } |
| 27 | 28 | ||
| 28 | @Override | 29 | @Override |
| 29 | - public void bindSocialUser(SocialUserBindReqDTO reqDTO) { | ||
| 30 | - socialUserService.bindSocialUser(reqDTO); | 30 | + public String bindSocialUser(SocialUserBindReqDTO reqDTO) { |
| 31 | + return socialUserService.bindSocialUser(reqDTO); | ||
| 31 | } | 32 | } |
| 32 | 33 | ||
| 33 | @Override | 34 | @Override |
| @@ -37,8 +38,8 @@ public class SocialUserApiImpl implements SocialUserApi { | @@ -37,8 +38,8 @@ public class SocialUserApiImpl implements SocialUserApi { | ||
| 37 | } | 38 | } |
| 38 | 39 | ||
| 39 | @Override | 40 | @Override |
| 40 | - public Long getBindUserId(Integer userType, Integer type, String code, String state) { | ||
| 41 | - return socialUserService.getBindUserId(userType, type, code, state); | 41 | + public SocialUserRespDTO getSocialUser(Integer userType, Integer type, String code, String state) { |
| 42 | + return socialUserService.getSocialUser(userType, type, code, state); | ||
| 42 | } | 43 | } |
| 43 | 44 | ||
| 44 | } | 45 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java
| @@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; | @@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; | ||
| 9 | import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO; | 9 | import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO; |
| 10 | import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; | 10 | import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; |
| 11 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; | 11 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 12 | +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; | ||
| 12 | import cn.iocoder.yudao.module.system.controller.admin.auth.vo.*; | 13 | import cn.iocoder.yudao.module.system.controller.admin.auth.vo.*; |
| 13 | import cn.iocoder.yudao.module.system.convert.auth.AuthConvert; | 14 | import cn.iocoder.yudao.module.system.convert.auth.AuthConvert; |
| 14 | import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; | 15 | import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; |
| @@ -155,14 +156,14 @@ public class AdminAuthServiceImpl implements AdminAuthService { | @@ -155,14 +156,14 @@ public class AdminAuthServiceImpl implements AdminAuthService { | ||
| 155 | @Override | 156 | @Override |
| 156 | public AuthLoginRespVO socialLogin(AuthSocialLoginReqVO reqVO) { | 157 | public AuthLoginRespVO socialLogin(AuthSocialLoginReqVO reqVO) { |
| 157 | // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号 | 158 | // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号 |
| 158 | - Long userId = socialUserService.getBindUserId(UserTypeEnum.ADMIN.getValue(), reqVO.getType(), | 159 | + SocialUserRespDTO socialUser = socialUserService.getSocialUser(UserTypeEnum.ADMIN.getValue(), reqVO.getType(), |
| 159 | reqVO.getCode(), reqVO.getState()); | 160 | reqVO.getCode(), reqVO.getState()); |
| 160 | - if (userId == null) { | 161 | + if (socialUser == null) { |
| 161 | throw exception(AUTH_THIRD_LOGIN_NOT_BIND); | 162 | throw exception(AUTH_THIRD_LOGIN_NOT_BIND); |
| 162 | } | 163 | } |
| 163 | 164 | ||
| 164 | // 获得用户 | 165 | // 获得用户 |
| 165 | - AdminUserDO user = userService.getUser(userId); | 166 | + AdminUserDO user = userService.getUser(socialUser.getUserId()); |
| 166 | if (user == null) { | 167 | if (user == null) { |
| 167 | throw exception(USER_NOT_EXISTS); | 168 | throw exception(USER_NOT_EXISTS); |
| 168 | } | 169 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserService.java
| @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.service.social; | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.service.social; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.exception.ServiceException; | 3 | import cn.iocoder.yudao.framework.common.exception.ServiceException; |
| 4 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; | 4 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 5 | +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; | ||
| 5 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; | 6 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; |
| 6 | import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; | 7 | import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; |
| 7 | 8 | ||
| @@ -50,8 +51,9 @@ public interface SocialUserService { | @@ -50,8 +51,9 @@ public interface SocialUserService { | ||
| 50 | * 绑定社交用户 | 51 | * 绑定社交用户 |
| 51 | * | 52 | * |
| 52 | * @param reqDTO 绑定信息 | 53 | * @param reqDTO 绑定信息 |
| 54 | + * @return 社交用户 openid | ||
| 53 | */ | 55 | */ |
| 54 | - void bindSocialUser(@Valid SocialUserBindReqDTO reqDTO); | 56 | + String bindSocialUser(@Valid SocialUserBindReqDTO reqDTO); |
| 55 | 57 | ||
| 56 | /** | 58 | /** |
| 57 | * 取消绑定社交用户 | 59 | * 取消绑定社交用户 |
| @@ -64,15 +66,16 @@ public interface SocialUserService { | @@ -64,15 +66,16 @@ public interface SocialUserService { | ||
| 64 | void unbindSocialUser(Long userId, Integer userType, Integer type, String openid); | 66 | void unbindSocialUser(Long userId, Integer userType, Integer type, String openid); |
| 65 | 67 | ||
| 66 | /** | 68 | /** |
| 67 | - * 获得社交用户的绑定用户编号 | ||
| 68 | - * 注意,返回的是 MemberUser 或者 AdminUser 的 id 编号! | 69 | + * 获得社交用户 |
| 70 | + * | ||
| 69 | * 在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常 | 71 | * 在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常 |
| 70 | * | 72 | * |
| 71 | * @param userType 用户类型 | 73 | * @param userType 用户类型 |
| 72 | * @param type 社交平台的类型 | 74 | * @param type 社交平台的类型 |
| 73 | * @param code 授权码 | 75 | * @param code 授权码 |
| 74 | * @param state state | 76 | * @param state state |
| 75 | - * @return 绑定用户编号 | 77 | + * @return 社交用户 |
| 76 | */ | 78 | */ |
| 77 | - Long getBindUserId(Integer userType, Integer type, String code, String state); | 79 | + SocialUserRespDTO getSocialUser(Integer userType, Integer type, String code, String state); |
| 80 | + | ||
| 78 | } | 81 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java
| @@ -5,6 +5,7 @@ import cn.hutool.core.lang.Assert; | @@ -5,6 +5,7 @@ import cn.hutool.core.lang.Assert; | ||
| 5 | import cn.iocoder.yudao.framework.common.util.http.HttpUtils; | 5 | import cn.iocoder.yudao.framework.common.util.http.HttpUtils; |
| 6 | import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory; | 6 | import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory; |
| 7 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; | 7 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 8 | +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; | ||
| 8 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; | 9 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; |
| 9 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; | 10 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; |
| 10 | import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper; | 11 | import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper; |
| @@ -98,7 +99,7 @@ public class SocialUserServiceImpl implements SocialUserService { | @@ -98,7 +99,7 @@ public class SocialUserServiceImpl implements SocialUserService { | ||
| 98 | 99 | ||
| 99 | @Override | 100 | @Override |
| 100 | @Transactional | 101 | @Transactional |
| 101 | - public void bindSocialUser(SocialUserBindReqDTO reqDTO) { | 102 | + public String bindSocialUser(SocialUserBindReqDTO reqDTO) { |
| 102 | // 获得社交用户 | 103 | // 获得社交用户 |
| 103 | SocialUserDO socialUser = authSocialUser(reqDTO.getType(), reqDTO.getCode(), reqDTO.getState()); | 104 | SocialUserDO socialUser = authSocialUser(reqDTO.getType(), reqDTO.getCode(), reqDTO.getState()); |
| 104 | Assert.notNull(socialUser, "社交用户不能为空"); | 105 | Assert.notNull(socialUser, "社交用户不能为空"); |
| @@ -115,6 +116,7 @@ public class SocialUserServiceImpl implements SocialUserService { | @@ -115,6 +116,7 @@ public class SocialUserServiceImpl implements SocialUserService { | ||
| 115 | .userId(reqDTO.getUserId()).userType(reqDTO.getUserType()) | 116 | .userId(reqDTO.getUserId()).userType(reqDTO.getUserType()) |
| 116 | .socialUserId(socialUser.getId()).socialType(socialUser.getType()).build(); | 117 | .socialUserId(socialUser.getId()).socialType(socialUser.getType()).build(); |
| 117 | socialUserBindMapper.insert(socialUserBind); | 118 | socialUserBindMapper.insert(socialUserBind); |
| 119 | + return socialUser.getOpenid(); | ||
| 118 | } | 120 | } |
| 119 | 121 | ||
| 120 | @Override | 122 | @Override |
| @@ -130,7 +132,7 @@ public class SocialUserServiceImpl implements SocialUserService { | @@ -130,7 +132,7 @@ public class SocialUserServiceImpl implements SocialUserService { | ||
| 130 | } | 132 | } |
| 131 | 133 | ||
| 132 | @Override | 134 | @Override |
| 133 | - public Long getBindUserId(Integer userType, Integer type, String code, String state) { | 135 | + public SocialUserRespDTO getSocialUser(Integer userType, Integer type, String code, String state) { |
| 134 | // 获得社交用户 | 136 | // 获得社交用户 |
| 135 | SocialUserDO socialUser = authSocialUser(type, code, state); | 137 | SocialUserDO socialUser = authSocialUser(type, code, state); |
| 136 | Assert.notNull(socialUser, "社交用户不能为空"); | 138 | Assert.notNull(socialUser, "社交用户不能为空"); |
| @@ -141,7 +143,7 @@ public class SocialUserServiceImpl implements SocialUserService { | @@ -141,7 +143,7 @@ public class SocialUserServiceImpl implements SocialUserService { | ||
| 141 | if (socialUserBind == null) { | 143 | if (socialUserBind == null) { |
| 142 | throw exception(AUTH_THIRD_LOGIN_NOT_BIND); | 144 | throw exception(AUTH_THIRD_LOGIN_NOT_BIND); |
| 143 | } | 145 | } |
| 144 | - return socialUserBind.getUserId(); | 146 | + return new SocialUserRespDTO(socialUser.getOpenid(), socialUserBind.getUserId()); |
| 145 | } | 147 | } |
| 146 | 148 | ||
| 147 | /** | 149 | /** |
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImplTest.java
| @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | ||
| 6 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | 6 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; |
| 7 | import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; | 7 | import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; |
| 8 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; | 8 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 9 | +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; | ||
| 9 | import cn.iocoder.yudao.module.system.controller.admin.auth.vo.*; | 10 | import cn.iocoder.yudao.module.system.controller.admin.auth.vo.*; |
| 10 | import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; | 11 | import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; |
| 11 | import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; | 12 | import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; |
| @@ -235,8 +236,8 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest { | @@ -235,8 +236,8 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest { | ||
| 235 | AuthSocialLoginReqVO reqVO = randomPojo(AuthSocialLoginReqVO.class); | 236 | AuthSocialLoginReqVO reqVO = randomPojo(AuthSocialLoginReqVO.class); |
| 236 | // mock 方法(绑定的用户编号) | 237 | // mock 方法(绑定的用户编号) |
| 237 | Long userId = 1L; | 238 | Long userId = 1L; |
| 238 | - when(socialUserService.getBindUserId(eq(UserTypeEnum.ADMIN.getValue()), eq(reqVO.getType()), | ||
| 239 | - eq(reqVO.getCode()), eq(reqVO.getState()))).thenReturn(userId); | 239 | + when(socialUserService.getSocialUser(eq(UserTypeEnum.ADMIN.getValue()), eq(reqVO.getType()), |
| 240 | + eq(reqVO.getCode()), eq(reqVO.getState()))).thenReturn(new SocialUserRespDTO(randomString(), userId)); | ||
| 240 | // mock(用户) | 241 | // mock(用户) |
| 241 | AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(userId)); | 242 | AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(userId)); |
| 242 | when(userService.getUser(eq(userId))).thenReturn(user); | 243 | when(userService.getUser(eq(userId))).thenReturn(user); |
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImplTest.java
| @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | ||
| 4 | import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory; | 4 | import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory; |
| 5 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | 5 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; |
| 6 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; | 6 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 7 | +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; | ||
| 7 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; | 8 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; |
| 8 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; | 9 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; |
| 9 | import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper; | 10 | import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper; |
| @@ -195,10 +196,11 @@ public class SocialUserServiceImplTest extends BaseDbUnitTest { | @@ -195,10 +196,11 @@ public class SocialUserServiceImplTest extends BaseDbUnitTest { | ||
| 195 | .setSocialType(SocialTypeEnum.GITEE.getType()).setSocialUserId(socialUser.getId())); | 196 | .setSocialType(SocialTypeEnum.GITEE.getType()).setSocialUserId(socialUser.getId())); |
| 196 | 197 | ||
| 197 | // 调用 | 198 | // 调用 |
| 198 | - socialUserService.bindSocialUser(reqDTO); | 199 | + String openid = socialUserService.bindSocialUser(reqDTO); |
| 199 | // 断言 | 200 | // 断言 |
| 200 | List<SocialUserBindDO> socialUserBinds = socialUserBindMapper.selectList(); | 201 | List<SocialUserBindDO> socialUserBinds = socialUserBindMapper.selectList(); |
| 201 | assertEquals(1, socialUserBinds.size()); | 202 | assertEquals(1, socialUserBinds.size()); |
| 203 | + assertEquals(socialUser.getOpenid(), openid); | ||
| 202 | } | 204 | } |
| 203 | 205 | ||
| 204 | @Test | 206 | @Test |
| @@ -232,25 +234,26 @@ public class SocialUserServiceImplTest extends BaseDbUnitTest { | @@ -232,25 +234,26 @@ public class SocialUserServiceImplTest extends BaseDbUnitTest { | ||
| 232 | } | 234 | } |
| 233 | 235 | ||
| 234 | @Test | 236 | @Test |
| 235 | - public void testGetBindUserId() { | 237 | + public void testGetSocialUser() { |
| 236 | // 准备参数 | 238 | // 准备参数 |
| 237 | Integer userType = UserTypeEnum.ADMIN.getValue(); | 239 | Integer userType = UserTypeEnum.ADMIN.getValue(); |
| 238 | Integer type = SocialTypeEnum.GITEE.getType(); | 240 | Integer type = SocialTypeEnum.GITEE.getType(); |
| 239 | String code = "tudou"; | 241 | String code = "tudou"; |
| 240 | String state = "yuanma"; | 242 | String state = "yuanma"; |
| 241 | // mock 社交用户 | 243 | // mock 社交用户 |
| 242 | - SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(type).setCode(code).setState(state); | ||
| 243 | - socialUserMapper.insert(socialUser); | 244 | + SocialUserDO socialUserDO = randomPojo(SocialUserDO.class).setType(type).setCode(code).setState(state); |
| 245 | + socialUserMapper.insert(socialUserDO); | ||
| 244 | // mock 社交用户的绑定 | 246 | // mock 社交用户的绑定 |
| 245 | Long userId = randomLong(); | 247 | Long userId = randomLong(); |
| 246 | SocialUserBindDO socialUserBind = randomPojo(SocialUserBindDO.class).setUserType(userType).setUserId(userId) | 248 | SocialUserBindDO socialUserBind = randomPojo(SocialUserBindDO.class).setUserType(userType).setUserId(userId) |
| 247 | - .setSocialType(type).setSocialUserId(socialUser.getId()); | 249 | + .setSocialType(type).setSocialUserId(socialUserDO.getId()); |
| 248 | socialUserBindMapper.insert(socialUserBind); | 250 | socialUserBindMapper.insert(socialUserBind); |
| 249 | 251 | ||
| 250 | // 调用 | 252 | // 调用 |
| 251 | - Long result = socialUserService.getBindUserId(userType, type, code, state); | 253 | + SocialUserRespDTO socialUser = socialUserService.getSocialUser(userType, type, code, state); |
| 252 | // 断言 | 254 | // 断言 |
| 253 | - assertEquals(userId, result); | 255 | + assertEquals(userId, socialUser.getUserId()); |
| 256 | + assertEquals(socialUserDO.getOpenid(), socialUser.getOpenid()); | ||
| 254 | } | 257 | } |
| 255 | 258 | ||
| 256 | } | 259 | } |
yudao-server/src/main/resources/application-local.yaml
| @@ -173,8 +173,10 @@ wx: | @@ -173,8 +173,10 @@ wx: | ||
| 173 | key-prefix: wx # Redis Key 的前缀 | 173 | key-prefix: wx # Redis Key 的前缀 |
| 174 | http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台 | 174 | http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台 |
| 175 | miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档 | 175 | miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档 |
| 176 | - appid: wx62056c0d5e8db250 | ||
| 177 | - secret: 333ae72f41552af1e998fe1f54e1584a | 176 | +# appid: wx62056c0d5e8db250 |
| 177 | +# secret: 333ae72f41552af1e998fe1f54e1584a | ||
| 178 | + appid: wx63c280fe3248a3e7 # wenhualian的接口测试号 | ||
| 179 | + secret: 6f270509224a7ae1296bbf1c8cb97aed | ||
| 178 | config-storage: | 180 | config-storage: |
| 179 | type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取 | 181 | type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取 |
| 180 | key-prefix: wa # Redis Key 的前缀 | 182 | key-prefix: wa # Redis Key 的前缀 |