🐛 修复小程序重新授权因空账号判空失败报 500 且 openid 无法绑定
system 侧 R.data(null) 被空值序列化写成 {},Feign 侧反序列化出 id 为空的
MpUser 而非 null,被当作「已查到」:换号撞键分支误置 openidOccupied,导致
openid 永不绑定并提示「该微信已绑定其他账号」;手机号查不到账号时还会以
空主键、空租户调用 bindOpenId,系统侧判缺参 400,再被 Feign 降级包成
AssertionError(Error 而非 Exception)逃出 catch (Exception),登录返回 500。
- 新增 presentAccount():以主键判定是否命中,findByOpenid/findByPhone 统一走它
- bindOpenid 入口加守卫:缺主键或租户只记 WARN 后跳过,不再发空参数请求
- 补 2 条单测:空对象 data 视为未命中;不落空主键账号、不发空主键绑定
This commit is contained in:
@@ -229,6 +229,44 @@ class MpLoginSupportTest {
|
||||
verify(mpUserClient, never()).bindOpenId(anyString(), anyLong(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("远端查无账号返回空对象(id 为空):按未命中建号,并用真实主键补绑 openid")
|
||||
void emptyAccountFromRemoteIsTreatedAsMiss() {
|
||||
// 服务端 R.data(null) 落 HTTP 是 {},Feign 反序列化成 id 为空的 MpUser 而非 null
|
||||
MpUser created = mpUser(61L, PHONE, null, "driver");
|
||||
when(mpUserClient.userByOpenid(TENANT_ID, OPENID)).thenReturn(R.data(new MpUser()));
|
||||
when(mpUserClient.userByPhone(TENANT_ID, PHONE)).thenReturn(R.data(new MpUser()));
|
||||
when(mpUserClient.ensureUser(any(MpUserEnsureDTO.class))).thenReturn(R.data(created));
|
||||
when(mpUserClient.bindOpenId(TENANT_ID, 61L, OPENID)).thenReturn(R.data(Boolean.TRUE));
|
||||
when(mpUserClient.userInfoById(61L)).thenReturn(R.data(userInfo(created, "driver")));
|
||||
when(driverClient.ensureProfile(any(DriverEnsureProfileDTO.class))).thenReturn(R.data(profileResult()));
|
||||
|
||||
OAuth2User user = mpLoginSupport.ensureLoginAccount(TENANT_ID, PHONE, OPENID);
|
||||
|
||||
assertNotNull(user);
|
||||
assertEquals("61", user.getUserId());
|
||||
assertNull(user.getDetail().get(MpLoginSupport.DETAIL_LOGIN_NOTICE), "不该出现换号撞键提示");
|
||||
verify(mpUserClient).ensureUser(any(MpUserEnsureDTO.class));
|
||||
verify(mpUserClient, never()).updateUser(any(MpUser.class));
|
||||
verify(mpUserClient).bindOpenId(TENANT_ID, 61L, OPENID);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("两个查询都返回空对象时:不落空账号、不发起带空主键的绑定")
|
||||
void emptyAccountDoesNotLeakNullIdentityIntoBind() {
|
||||
MpUser created = mpUser(62L, PHONE, OPENID, "driver");
|
||||
when(mpUserClient.userByOpenid(TENANT_ID, OPENID)).thenReturn(R.data(new MpUser()));
|
||||
when(mpUserClient.userByPhone(TENANT_ID, PHONE)).thenReturn(R.data(new MpUser()));
|
||||
when(mpUserClient.ensureUser(any(MpUserEnsureDTO.class))).thenReturn(R.data(created));
|
||||
when(mpUserClient.userInfoById(62L)).thenReturn(R.data(userInfo(created, "driver")));
|
||||
when(driverClient.ensureProfile(any(DriverEnsureProfileDTO.class))).thenReturn(R.data(profileResult()));
|
||||
|
||||
OAuth2User user = mpLoginSupport.ensureLoginAccount(TENANT_ID, PHONE, OPENID);
|
||||
|
||||
assertEquals("62", user.getUserId());
|
||||
verify(mpUserClient, never()).bindOpenId(anyString(), anyLong(), anyString());
|
||||
}
|
||||
|
||||
private MpUser mpUser(Long id, String phone, String openid, String identities) {
|
||||
MpUser user = new MpUser();
|
||||
user.setId(id);
|
||||
|
||||
Reference in New Issue
Block a user