Commit 40e1a879e3b38d830b25f81716986d485f115d61

Authored by YunaiV
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 的前缀