🩹 登录建号租户改为优先取 Tenant-Id 请求头
接口契约要求 Tenant-Id 头 → tenant_id 参数 → 兜底 000000。 写库前仍兜到非空;入参与请求头不一致时以请求头为准。 同步订正两个 DTO 的 tenantId 说明。
This commit is contained in:
+1
-1
@@ -43,7 +43,7 @@ public class DriverEnsureProfileDTO implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "租户ID,为空时取当前登录租户;仍为空则拒绝写库")
|
||||
@Schema(description = "租户ID,为空时取当前请求租户;仍为空则拒绝写库")
|
||||
private String tenantId;
|
||||
|
||||
@Schema(description = "关联小程序用户ID(blade_mp_user.id)")
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ public class MpUserEnsureDTO implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "租户ID,为空时依次取当前登录租户与默认租户")
|
||||
@Schema(description = "租户ID,为空时依次取 Tenant-Id 请求头与默认租户")
|
||||
private String tenantId;
|
||||
|
||||
@Schema(description = "手机号")
|
||||
|
||||
+27
-9
@@ -24,6 +24,7 @@ package org.springblade.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springblade.common.utils.PasswordRuleUtil;
|
||||
@@ -35,6 +36,7 @@ import org.springblade.core.tool.utils.DateUtil;
|
||||
import org.springblade.core.tool.utils.DigestUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.core.tool.utils.StringUtil;
|
||||
import org.springblade.core.tool.utils.WebUtil;
|
||||
import org.springblade.system.cache.MpUserCache;
|
||||
import org.springblade.system.mapper.MpUserMapper;
|
||||
import org.springblade.system.pojo.dto.MpUserEnsureDTO;
|
||||
@@ -65,6 +67,11 @@ public class MpUserServiceImpl extends BaseServiceImpl<MpUserMapper, MpUser> imp
|
||||
*/
|
||||
private static final String DEFAULT_TENANT_ID = "000000";
|
||||
|
||||
/**
|
||||
* 登录请求携带租户的请求头名
|
||||
*/
|
||||
private static final String TENANT_HEADER = "Tenant-Id";
|
||||
|
||||
@Override
|
||||
public MpUser getByPhone(String tenantId, String phone) {
|
||||
if (Func.isBlank(tenantId) || Func.isBlank(phone)) {
|
||||
@@ -127,12 +134,12 @@ public class MpUserServiceImpl extends BaseServiceImpl<MpUserMapper, MpUser> imp
|
||||
user.setStatus(1);
|
||||
prepare(user);
|
||||
validate(user);
|
||||
// 登录路径不设密码:密码留空,避免调用方误传弱口令
|
||||
// 登录路径不设密码,password 保持为空
|
||||
user.setPassword(null);
|
||||
try {
|
||||
save(user);
|
||||
} catch (Exception exception) {
|
||||
// 并发建号撞 (tenant_id, phone) 唯一键:重读一次返回,登录方不该因重试失败
|
||||
// 并发建号撞 (tenant_id, phone) 唯一键:重读一次并返回已有账号
|
||||
MpUser concurrent = getByPhone(tenantId, phone);
|
||||
if (concurrent != null && Func.isNotEmpty(concurrent.getId())) {
|
||||
return concurrent;
|
||||
@@ -148,15 +155,15 @@ public class MpUserServiceImpl extends BaseServiceImpl<MpUserMapper, MpUser> imp
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录路径的租户解析:入参 → 当前登录租户 → 默认租户
|
||||
* 登录路径的租户解析:Tenant-Id 头 → 入参 tenantId → 默认租户
|
||||
* <p>
|
||||
* 写库前必须得到非空值:唯一键 (tenant_id, phone) 对 NULL 不去重,租户为 NULL
|
||||
* 会为同一手机号造出重复账号。
|
||||
* 请求头与入参不一致时以请求头为准。写库前必须得到非空值:唯一键 (tenant_id, phone)
|
||||
* 对 NULL 不去重,租户为 NULL 会为同一手机号造出重复账号。
|
||||
*/
|
||||
private String resolveEnsureTenantId(String tenantId) {
|
||||
String resolved = trimToNull(tenantId);
|
||||
String resolved = requestHeaderTenantId();
|
||||
if (resolved == null) {
|
||||
resolved = trimToNull(AuthUtil.getTenantId());
|
||||
resolved = trimToNull(tenantId);
|
||||
}
|
||||
if (resolved == null) {
|
||||
resolved = DEFAULT_TENANT_ID;
|
||||
@@ -164,6 +171,17 @@ public class MpUserServiceImpl extends BaseServiceImpl<MpUserMapper, MpUser> imp
|
||||
return resolved;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前请求头里的租户;无请求上下文时返回 null
|
||||
*/
|
||||
private String requestHeaderTenantId() {
|
||||
HttpServletRequest request = WebUtil.getRequest();
|
||||
if (request == null) {
|
||||
return null;
|
||||
}
|
||||
return trimToNull(request.getHeader(TENANT_HEADER));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MpUserInfo userInfo(Long userId) {
|
||||
if (Func.isEmpty(userId)) {
|
||||
@@ -319,8 +337,8 @@ public class MpUserServiceImpl extends BaseServiceImpl<MpUserMapper, MpUser> imp
|
||||
if (!tenantId.equals(user.getTenantId())) {
|
||||
throw new ServiceException("租户不匹配,无法绑定 openid");
|
||||
}
|
||||
// 目标账号已有另一个非空 openid 时不得覆盖:旧逻辑会静默顶掉上一个微信的绑定,
|
||||
// 而一个微信换绑需要管理员确认,登录路径只放弃本次绑定(票 05)
|
||||
// 目标账号已有另一个非空 openid 时不覆盖:一个微信换绑由管理员处理,
|
||||
// 登录路径直接放弃本次绑定
|
||||
if (Func.isNotBlank(user.getOpenid()) && !user.getOpenid().equals(openid)) {
|
||||
log.warn("小程序用户已绑定其他 openid,跳过绑定:租户={} 账号={} 已有openid={} 本次openid={}",
|
||||
tenantId, userId, user.getOpenid(), openid);
|
||||
|
||||
Reference in New Issue
Block a user