WxMiniAppPhoneCodeAuthenticationProvider.java 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package com.zsElectric.boot.security.provider;
  2. import cn.binarywang.wx.miniapp.api.WxMaService;
  3. import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
  4. import cn.hutool.core.util.StrUtil;
  5. import com.zsElectric.boot.business.model.entity.UserInfo;
  6. import com.zsElectric.boot.business.service.UserInfoService;
  7. import com.zsElectric.boot.security.model.WxMiniAppPhoneCodeAuthenticationToken;
  8. import lombok.extern.slf4j.Slf4j;
  9. import me.chanjar.weixin.common.error.WxErrorException;
  10. import org.springframework.security.authentication.AuthenticationProvider;
  11. import org.springframework.security.authentication.CredentialsExpiredException;
  12. import org.springframework.security.core.Authentication;
  13. import org.springframework.security.core.AuthenticationException;
  14. import org.springframework.security.core.userdetails.UsernameNotFoundException;
  15. /**
  16. * 微信小程序手机号Code认证Provider(新版接口)
  17. *
  18. * @author Ray.Hao
  19. * @since 2.0.0
  20. */
  21. @Slf4j
  22. public class WxMiniAppPhoneCodeAuthenticationProvider implements AuthenticationProvider {
  23. private final UserInfoService userInfoService;
  24. private final WxMaService wxMaService;
  25. public WxMiniAppPhoneCodeAuthenticationProvider(UserInfoService userInfoService, WxMaService wxMaService) {
  26. this.userInfoService = userInfoService;
  27. this.wxMaService = wxMaService;
  28. }
  29. @Override
  30. public Authentication authenticate(Authentication authentication) throws AuthenticationException {
  31. WxMiniAppPhoneCodeAuthenticationToken authenticationToken = (WxMiniAppPhoneCodeAuthenticationToken) authentication;
  32. String phoneCode = (String) authenticationToken.getPrincipal();
  33. // 1. 通过phoneCode获取手机号信息(新版接口)
  34. WxMaPhoneNumberInfo phoneNumberInfo;
  35. try {
  36. phoneNumberInfo = wxMaService.getUserService().getPhoneNoInfo(phoneCode);
  37. } catch (WxErrorException e) {
  38. log.error("获取微信手机号失败", e);
  39. throw new CredentialsExpiredException("获取手机号失败,code无效或已过期");
  40. }
  41. if (phoneNumberInfo == null || StrUtil.isBlank(phoneNumberInfo.getPhoneNumber())) {
  42. throw new CredentialsExpiredException("获取手机号失败");
  43. }
  44. String phoneNumber = phoneNumberInfo.getPhoneNumber();
  45. log.info("通过code获取到手机号: {}", phoneNumber);
  46. // 2. 根据手机号注册或更新用户(c_user_info表)
  47. UserInfo userInfo = userInfoService.registerOrUpdateUserByPhone(phoneNumber, null);
  48. if (userInfo == null) {
  49. throw new UsernameNotFoundException("用户注册失败");
  50. }
  51. log.info("用户信息获取成功,ID: {}, 手机号: {}", userInfo.getId(), userInfo.getPhone());
  52. // 3. 构建小程序用户详情
  53. AppletUserDetails userDetails = new AppletUserDetails();
  54. userDetails.setUserId(userInfo.getId());
  55. userDetails.setPhone(userInfo.getPhone());
  56. userDetails.setOpenid(userInfo.getOpenid());
  57. userDetails.setNickname(userInfo.getNickName());
  58. userDetails.setEnabled(true);
  59. // 4. 创建已认证的Token
  60. return WxMiniAppPhoneCodeAuthenticationToken.authenticated(
  61. userDetails,
  62. userDetails.getAuthorities()
  63. );
  64. }
  65. @Override
  66. public boolean supports(Class<?> authentication) {
  67. return WxMiniAppPhoneCodeAuthenticationToken.class.isAssignableFrom(authentication);
  68. }
  69. }