From c3edca04a5d5c5c41e66b92d7e69640395a2552e Mon Sep 17 00:00:00 2001 From: b2894lxlx <517289602@qq.com> Date: Mon, 12 Oct 2026 14:22:33 +0800 Subject: [PATCH] =?UTF-8?q?:zap:=20=E5=B0=8F=E7=A8=8B=E5=BA=8F=E5=AF=86?= =?UTF-8?q?=E7=A0=81/=E7=9F=AD=E4=BF=A1=E7=99=BB=E5=BD=95=E6=8C=89=20User-?= =?UTF-8?q?Type=3Dmp=20=E8=B5=B0=20blade=5Fmp=5Fuser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- .../auth/endpoint/Oauth2SmsEndpoint.java | 3 +- .../auth/service/BladeUserDetailService.java | 69 ++++++++++--------- 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/blade-auth/src/main/java/org/springblade/auth/endpoint/Oauth2SmsEndpoint.java b/blade-auth/src/main/java/org/springblade/auth/endpoint/Oauth2SmsEndpoint.java index b48ac804..dfa3b898 100644 --- a/blade-auth/src/main/java/org/springblade/auth/endpoint/Oauth2SmsEndpoint.java +++ b/blade-auth/src/main/java/org/springblade/auth/endpoint/Oauth2SmsEndpoint.java @@ -88,7 +88,8 @@ public class Oauth2SmsEndpoint { return R.fail(USER_PHONE_NOT_FOUND); } // 校验手机是否已注册,防止恶意发送验证码 - OAuth2Request request = OAuth2Request.create(); + // buildArgs:带上 User-Type 等请求头,小程序传 User-Type=mp 时查 blade_mp_user + OAuth2Request request = OAuth2Request.create().buildArgs(); request.setTenantId(tenantId); OAuth2User oAuth2User = userService.loadByPhone(decryptedPhone, request); if (oAuth2User == null) { diff --git a/blade-auth/src/main/java/org/springblade/auth/service/BladeUserDetailService.java b/blade-auth/src/main/java/org/springblade/auth/service/BladeUserDetailService.java index fa5cbc46..22904efe 100644 --- a/blade-auth/src/main/java/org/springblade/auth/service/BladeUserDetailService.java +++ b/blade-auth/src/main/java/org/springblade/auth/service/BladeUserDetailService.java @@ -53,13 +53,8 @@ public class BladeUserDetailService implements OAuth2UserService { @Override public OAuth2User loadByUserId(String userId, OAuth2Request request) { - // 获取用户参数 - String userType = Optional.ofNullable(request.getUserType()) - .filter(s -> !StringUtil.isBlank(s)) - .orElse(UserType.WEB.getName()); - - // 小程序刷新/鉴权:直接查 blade_mp_user - if (MpUserIdentity.DETAIL_TYPE.equalsIgnoreCase(userType)) { + // 小程序刷新/鉴权:User-Type=mp 时只查 blade_mp_user + if (isMpLoginRequest(request)) { OAuth2User mpUser = loadMpUserById(userId); if (mpUser == null) { OAuth2ExceptionUtil.throwFromCode(OAuth2ErrorCode.INVALID_USER); @@ -67,14 +62,14 @@ public class BladeUserDetailService implements OAuth2UserService { return mpUser; } - // 系统用户 + String userType = resolveUserType(request); R result = userClient.userInfo(Func.toLong(userId), userType); if (result != null && result.isSuccess() && result.getData() != null && result.getData().getUser() != null) { return TokenUtil.convertUser(result.getData(), request); } - // 兼容:未带 userType=mp 时,回落查询小程序用户(令牌刷新) + // 兼容:刷新令牌未带 User-Type=mp 时,回落查询小程序用户 OAuth2User mpUser = loadMpUserById(userId); if (mpUser != null) { return mpUser; @@ -85,14 +80,10 @@ public class BladeUserDetailService implements OAuth2UserService { @Override public OAuth2User loadByUsername(String username, OAuth2Request request) { - // 获取用户参数 - String userType = Optional.ofNullable(request.getUserType()) - .filter(s -> !StringUtil.isBlank(s)) - .orElse(UserType.WEB.getName()); String tenantId = request.getTenantId(); - // 小程序用户:按账号查 blade_mp_user - if (MpUserIdentity.DETAIL_TYPE.equalsIgnoreCase(userType)) { + // 小程序账号密码 / 图形验证码登录:仅查 blade_mp_user + if (isMpLoginRequest(request)) { R mpResult = mpUserClient.userInfoByAccount(tenantId, username); if (mpResult == null || !mpResult.isSuccess() || mpResult.getData() == null) { return null; @@ -100,43 +91,55 @@ public class BladeUserDetailService implements OAuth2UserService { return TokenUtil.convertMpUser(mpResult.getData()); } - // 获取用户信息 + String userType = resolveUserType(request); R result = userClient.userInfo(tenantId, username, userType); - if (!result.isSuccess()) { + if (result == null || !result.isSuccess()) { return null; } - // 构建oauth2用户信息 return TokenUtil.convertUser(result.getData(), request); } @Override public OAuth2User loadByPhone(String phone, OAuth2Request request) { - // 获取用户参数 - String userType = Optional.ofNullable(request.getUserType()) - .filter(s -> !StringUtil.isBlank(s)) - .orElse(UserType.WEB.getName()); String tenantId = request.getTenantId(); - // 小程序用户类型:仅查 blade_mp_user - if (MpUserIdentity.DETAIL_TYPE.equalsIgnoreCase(userType)) { + // 小程序短信登录:仅查 blade_mp_user + if (isMpLoginRequest(request)) { return loadMpUserByPhone(tenantId, phone); } - // 获取用户信息 + String userType = resolveUserType(request); R result = userClient.userInfoByPhone(tenantId, phone, userType); - if (!result.isSuccess()) { - return null; + if (result != null && result.isSuccess() && result.getData() != null) { + return TokenUtil.convertUser(result.getData(), request); } - // 构建oauth2用户信息 - return TokenUtil.convertUser(result.getData(), request); + // 发短信校验等未带 User-Type 时,回落小程序用户,避免 mp 账号收不到验证码 + return loadMpUserByPhone(tenantId, phone); } @Override public boolean validateUser(OAuth2User user) { return Optional.ofNullable(user) - .filter(u -> u.getUserId() != null && !u.getUserId().isEmpty()) // 检查userId不为空 - .filter(u -> u.getAuthorities() != null && !u.getAuthorities().isEmpty()) // 检查authorities不为空 - .isPresent(); // 如果上述条件都满足,则返回true,否则返回false + .filter(u -> u.getUserId() != null && !u.getUserId().isEmpty()) + .filter(u -> u.getAuthorities() != null && !u.getAuthorities().isEmpty()) + .isPresent(); + } + + /** + * 是否小程序登录:请求头 User-Type=mp(Web 与小程序共用 saber3 客户端,不能按 clientId 分流) + */ + private boolean isMpLoginRequest(OAuth2Request request) { + return request != null && isMpUserType(request.getUserType()); + } + + private boolean isMpUserType(String userType) { + return MpUserIdentity.DETAIL_TYPE.equalsIgnoreCase(Func.toStr(userType)); + } + + private String resolveUserType(OAuth2Request request) { + return Optional.ofNullable(request.getUserType()) + .filter(s -> !StringUtil.isBlank(s)) + .orElse(UserType.WEB.getName()); } private OAuth2User loadMpUserById(String userId) { @@ -150,7 +153,7 @@ public class BladeUserDetailService implements OAuth2UserService { return TokenUtil.convertMpUser(result.getData()); } } catch (Exception exception) { - // 非小程序用户场景忽略,继续走系统用户 + // 非小程序用户场景忽略 } return null; }