登录:社交登录时,额外返回 openid

This commit is contained in:
YunaiV
2023-09-10 18:01:53 +08:00
parent 4265441e1d
commit 40e1a879e3
13 changed files with 111 additions and 46 deletions

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.system.api.social;
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO;
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO;
import cn.iocoder.yudao.module.system.service.social.SocialUserService;
import org.springframework.stereotype.Service;
@ -26,8 +27,8 @@ public class SocialUserApiImpl implements SocialUserApi {
}
@Override
public void bindSocialUser(SocialUserBindReqDTO reqDTO) {
socialUserService.bindSocialUser(reqDTO);
public String bindSocialUser(SocialUserBindReqDTO reqDTO) {
return socialUserService.bindSocialUser(reqDTO);
}
@Override
@ -37,8 +38,8 @@ public class SocialUserApiImpl implements SocialUserApi {
}
@Override
public Long getBindUserId(Integer userType, Integer type, String code, String state) {
return socialUserService.getBindUserId(userType, type, code, state);
public SocialUserRespDTO getSocialUser(Integer userType, Integer type, String code, String state) {
return socialUserService.getSocialUser(userType, type, code, state);
}
}

View File

@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
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.dto.SocialUserBindReqDTO;
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO;
import cn.iocoder.yudao.module.system.controller.admin.auth.vo.*;
import cn.iocoder.yudao.module.system.convert.auth.AuthConvert;
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
@ -155,14 +156,14 @@ public class AdminAuthServiceImpl implements AdminAuthService {
@Override
public AuthLoginRespVO socialLogin(AuthSocialLoginReqVO reqVO) {
// 使用 code 授权码,进行登录。然后,获得到绑定的用户编号
Long userId = socialUserService.getBindUserId(UserTypeEnum.ADMIN.getValue(), reqVO.getType(),
SocialUserRespDTO socialUser = socialUserService.getSocialUser(UserTypeEnum.ADMIN.getValue(), reqVO.getType(),
reqVO.getCode(), reqVO.getState());
if (userId == null) {
if (socialUser == null) {
throw exception(AUTH_THIRD_LOGIN_NOT_BIND);
}
// 获得用户
AdminUserDO user = userService.getUser(userId);
AdminUserDO user = userService.getUser(socialUser.getUserId());
if (user == null) {
throw exception(USER_NOT_EXISTS);
}

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.service.social;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO;
import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
@ -50,8 +51,9 @@ public interface SocialUserService {
* 绑定社交用户
*
* @param reqDTO 绑定信息
* @return 社交用户 openid
*/
void bindSocialUser(@Valid SocialUserBindReqDTO reqDTO);
String bindSocialUser(@Valid SocialUserBindReqDTO reqDTO);
/**
* 取消绑定社交用户
@ -64,15 +66,16 @@ public interface SocialUserService {
void unbindSocialUser(Long userId, Integer userType, Integer type, String openid);
/**
* 获得社交用户的绑定用户编号
* 注意,返回的是 MemberUser 或者 AdminUser 的 id 编号!
* 获得社交用户
*
* 在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常
*
* @param userType 用户类型
* @param type 社交平台的类型
* @param code 授权码
* @param state state
* @return 绑定用户编号
* @return 社交用户
*/
Long getBindUserId(Integer userType, Integer type, String code, String state);
SocialUserRespDTO getSocialUser(Integer userType, Integer type, String code, String state);
}

View File

@ -5,6 +5,7 @@ import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory;
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO;
import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO;
import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper;
@ -98,7 +99,7 @@ public class SocialUserServiceImpl implements SocialUserService {
@Override
@Transactional
public void bindSocialUser(SocialUserBindReqDTO reqDTO) {
public String bindSocialUser(SocialUserBindReqDTO reqDTO) {
// 获得社交用户
SocialUserDO socialUser = authSocialUser(reqDTO.getType(), reqDTO.getCode(), reqDTO.getState());
Assert.notNull(socialUser, "社交用户不能为空");
@ -115,6 +116,7 @@ public class SocialUserServiceImpl implements SocialUserService {
.userId(reqDTO.getUserId()).userType(reqDTO.getUserType())
.socialUserId(socialUser.getId()).socialType(socialUser.getType()).build();
socialUserBindMapper.insert(socialUserBind);
return socialUser.getOpenid();
}
@Override
@ -130,7 +132,7 @@ public class SocialUserServiceImpl implements SocialUserService {
}
@Override
public Long getBindUserId(Integer userType, Integer type, String code, String state) {
public SocialUserRespDTO getSocialUser(Integer userType, Integer type, String code, String state) {
// 获得社交用户
SocialUserDO socialUser = authSocialUser(type, code, state);
Assert.notNull(socialUser, "社交用户不能为空");
@ -141,7 +143,7 @@ public class SocialUserServiceImpl implements SocialUserService {
if (socialUserBind == null) {
throw exception(AUTH_THIRD_LOGIN_NOT_BIND);
}
return socialUserBind.getUserId();
return new SocialUserRespDTO(socialUser.getOpenid(), socialUserBind.getUserId());
}
/**

View File

@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO;
import cn.iocoder.yudao.module.system.controller.admin.auth.vo.*;
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
@ -235,8 +236,8 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest {
AuthSocialLoginReqVO reqVO = randomPojo(AuthSocialLoginReqVO.class);
// mock 方法(绑定的用户编号)
Long userId = 1L;
when(socialUserService.getBindUserId(eq(UserTypeEnum.ADMIN.getValue()), eq(reqVO.getType()),
eq(reqVO.getCode()), eq(reqVO.getState()))).thenReturn(userId);
when(socialUserService.getSocialUser(eq(UserTypeEnum.ADMIN.getValue()), eq(reqVO.getType()),
eq(reqVO.getCode()), eq(reqVO.getState()))).thenReturn(new SocialUserRespDTO(randomString(), userId));
// mock用户
AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(userId));
when(userService.getUser(eq(userId))).thenReturn(user);

View File

@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO;
import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO;
import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper;
@ -195,10 +196,11 @@ public class SocialUserServiceImplTest extends BaseDbUnitTest {
.setSocialType(SocialTypeEnum.GITEE.getType()).setSocialUserId(socialUser.getId()));
// 调用
socialUserService.bindSocialUser(reqDTO);
String openid = socialUserService.bindSocialUser(reqDTO);
// 断言
List<SocialUserBindDO> socialUserBinds = socialUserBindMapper.selectList();
assertEquals(1, socialUserBinds.size());
assertEquals(socialUser.getOpenid(), openid);
}
@Test
@ -232,25 +234,26 @@ public class SocialUserServiceImplTest extends BaseDbUnitTest {
}
@Test
public void testGetBindUserId() {
public void testGetSocialUser() {
// 准备参数
Integer userType = UserTypeEnum.ADMIN.getValue();
Integer type = SocialTypeEnum.GITEE.getType();
String code = "tudou";
String state = "yuanma";
// mock 社交用户
SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(type).setCode(code).setState(state);
socialUserMapper.insert(socialUser);
SocialUserDO socialUserDO = randomPojo(SocialUserDO.class).setType(type).setCode(code).setState(state);
socialUserMapper.insert(socialUserDO);
// mock 社交用户的绑定
Long userId = randomLong();
SocialUserBindDO socialUserBind = randomPojo(SocialUserBindDO.class).setUserType(userType).setUserId(userId)
.setSocialType(type).setSocialUserId(socialUser.getId());
.setSocialType(type).setSocialUserId(socialUserDO.getId());
socialUserBindMapper.insert(socialUserBind);
// 调用
Long result = socialUserService.getBindUserId(userType, type, code, state);
SocialUserRespDTO socialUser = socialUserService.getSocialUser(userType, type, code, state);
// 断言
assertEquals(userId, result);
assertEquals(userId, socialUser.getUserId());
assertEquals(socialUserDO.getOpenid(), socialUser.getOpenid());
}
}