diff --git a/blade-auth/src/main/java/org/springblade/auth/granter/SmsTokenGranter.java b/blade-auth/src/main/java/org/springblade/auth/granter/SmsTokenGranter.java index 540095c0..b79f8497 100644 --- a/blade-auth/src/main/java/org/springblade/auth/granter/SmsTokenGranter.java +++ b/blade-auth/src/main/java/org/springblade/auth/granter/SmsTokenGranter.java @@ -27,6 +27,7 @@ package org.springblade.auth.granter; import jakarta.servlet.http.HttpServletRequest; import org.springblade.auth.constant.BladeAuthConstant; +import org.springblade.auth.service.MpLoginSupport; import org.springblade.core.oauth2.constant.OAuth2TokenConstant; import org.springblade.core.oauth2.exception.UserInvalidException; import org.springblade.core.oauth2.granter.AbstractTokenGranter; @@ -43,10 +44,15 @@ import org.springblade.core.tool.utils.SM2Util; import org.springblade.core.tool.utils.StringUtil; import org.springblade.core.tool.utils.WebUtil; import org.springblade.resource.feign.ISmsClient; +import org.springblade.system.pojo.enums.MpUserIdentity; import org.springframework.stereotype.Component; /** * SmsTokenGranter + *
+ * 除验证码校验外,还要按请求来源分流:小程序(User-Type: mp)登录时账号不存在要自动建, + * Web 短信登录保持原样不建号。建号逻辑不能下沉到 {@code BladeUserDetailService.loadByPhone}, + * 那条方法还被「发送短信验证码」复用,会在发码时就建出账号(刷号)。 * * @author BladeX */ @@ -56,12 +62,14 @@ public class SmsTokenGranter extends AbstractTokenGranter { private final OAuth2UserService userService; private final ISmsClient smsClient; private final OAuth2Properties properties; + private final MpLoginSupport mpLoginSupport; - public SmsTokenGranter(OAuth2ClientService clientService, OAuth2UserService userService, PasswordHandler passwordHandler, ISmsClient smsClient, OAuth2Properties properties) { + public SmsTokenGranter(OAuth2ClientService clientService, OAuth2UserService userService, PasswordHandler passwordHandler, ISmsClient smsClient, OAuth2Properties properties, MpLoginSupport mpLoginSupport) { super(clientService, userService, passwordHandler); this.userService = userService; this.smsClient = smsClient; this.properties = properties; + this.mpLoginSupport = mpLoginSupport; } @Override @@ -86,8 +94,10 @@ public class SmsTokenGranter extends AbstractTokenGranter { if (!result.isSuccess()) { throw new UserInvalidException(OAuth2TokenConstant.CAPTCHA_NOT_CORRECT); } - // 获取用户信息 - OAuth2User user = userService.loadByPhone(decryptedPhone, request); + // 获取用户信息:只有小程序登录才允许自动建号,Web 短信登录仍走原查询 + OAuth2User user = isMpLoginRequest(request) + ? mpLoginSupport.ensureLoginAccount(tenantId, decryptedPhone, null) + : userService.loadByPhone(decryptedPhone, request); // 校验用户信息 if (!userService.validateUser(user)) { throw new UserInvalidException(OAuth2TokenConstant.TOKEN_NOT_CORRECT); @@ -97,6 +107,13 @@ public class SmsTokenGranter extends AbstractTokenGranter { return user; } + /** + * 是否小程序登录:请求头 User-Type=mp(Web 与小程序共用客户端,不能按 clientId 分流) + */ + private boolean isMpLoginRequest(OAuth2Request request) { + return request != null && MpUserIdentity.DETAIL_TYPE.equalsIgnoreCase(Func.toStr(request.getUserType())); + } + private SmsCode buildSmsCode() { HttpServletRequest request = WebUtil.getRequest(); return new SmsCode().setId(request.getParameter("id")) diff --git a/blade-auth/src/main/java/org/springblade/auth/granter/WechatMiniTokenGranter.java b/blade-auth/src/main/java/org/springblade/auth/granter/WechatMiniTokenGranter.java index 33de5291..101387c8 100644 --- a/blade-auth/src/main/java/org/springblade/auth/granter/WechatMiniTokenGranter.java +++ b/blade-auth/src/main/java/org/springblade/auth/granter/WechatMiniTokenGranter.java @@ -2,7 +2,7 @@ package org.springblade.auth.granter; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; -import org.springblade.auth.utils.TokenUtil; +import org.springblade.auth.service.MpLoginSupport; import org.springblade.core.oauth2.exception.UserInvalidException; import org.springblade.core.oauth2.granter.AbstractTokenGranter; import org.springblade.core.oauth2.handler.PasswordHandler; @@ -11,12 +11,9 @@ import org.springblade.core.oauth2.service.OAuth2Client; import org.springblade.core.oauth2.service.OAuth2ClientService; import org.springblade.core.oauth2.service.OAuth2User; import org.springblade.core.oauth2.service.OAuth2UserService; -import org.springblade.core.tool.api.R; 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.feign.IMpUserClient; -import org.springblade.system.pojo.entity.MpUserInfo; import org.springblade.thirdparty.wechat.constant.WechatMiniConstant; import org.springblade.thirdparty.wechat.exception.WechatMiniException; import org.springblade.thirdparty.wechat.pojo.vo.WechatPhoneVO; @@ -28,8 +25,8 @@ import org.springframework.stereotype.Component; * 微信小程序手机号一键登录。 *
* grant_type=wechat_applet,参数:loginCode(wx.login)、phoneCode(getPhoneNumber)。
- * 流程:换 openid + 手机号 → 按手机号查小程序用户(blade_mp_user,不存在则拒绝)
- * → 记录 openid → 按身份发令牌(不依赖系统角色)。
+ * 流程:换 openid + 手机号 → 由 {@link MpLoginSupport} 找到或创建账号并补齐档案
+ * → 按身份发令牌(不依赖系统角色)。
*/
@Slf4j
@Component
@@ -37,17 +34,17 @@ public class WechatMiniTokenGranter extends AbstractTokenGranter {
private final OAuth2UserService userService;
private final IWechatMiniService wechatMiniService;
- private final IMpUserClient mpUserClient;
+ private final MpLoginSupport mpLoginSupport;
public WechatMiniTokenGranter(OAuth2ClientService clientService,
OAuth2UserService userService,
PasswordHandler passwordHandler,
IWechatMiniService wechatMiniService,
- IMpUserClient mpUserClient) {
+ MpLoginSupport mpLoginSupport) {
super(clientService, userService, passwordHandler);
this.userService = userService;
this.wechatMiniService = wechatMiniService;
- this.mpUserClient = mpUserClient;
+ this.mpLoginSupport = mpLoginSupport;
}
@Override
@@ -82,28 +79,12 @@ public class WechatMiniTokenGranter extends AbstractTokenGranter {
throw new UserInvalidException("未获取到微信手机号");
}
- R