java springboot+uniapp实现微信小程序获取微信手机号

这篇具有很好参考价值的文章主要介绍了java springboot+uniapp实现微信小程序获取微信手机号。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前期准备

登录微信公众平台

https://mp.weixin.qq.com/
用此功能可能需要首页一些列认证完成后才可以:eg:小程序备案、微信认证等
java springboot+uniapp实现微信小程序获取微信手机号,uniapp,微信小程序获取手机号,java,spring boot,uni-app,微信小程序

1、获取AppId和AppSecret

侧开发管理->开发设置->需要获取 AppID(小程序ID)、**AppSecret(小程序密钥) **。
注意:AppSecret第一次生成后需要自己复制保存,后续虽然可以重置但是重置会相对麻烦。
java springboot+uniapp实现微信小程序获取微信手机号,uniapp,微信小程序获取手机号,java,spring boot,uni-app,微信小程序

2、更新隐私协议

左侧最底部设置(或点击右上角头像)->基本设置->服务内容声明->用户隐私保护指引 需要更新隐私协议否则后面会影响小程序按钮呼叫不出选择手机号的弹窗。隐私内容根据个人小程序用途如实填写即可。
java springboot+uniapp实现微信小程序获取微信手机号,uniapp,微信小程序获取手机号,java,spring boot,uni-app,微信小程序
java springboot+uniapp实现微信小程序获取微信手机号,uniapp,微信小程序获取手机号,java,spring boot,uni-app,微信小程序java springboot+uniapp实现微信小程序获取微信手机号,uniapp,微信小程序获取手机号,java,spring boot,uni-app,微信小程序
java springboot+uniapp实现微信小程序获取微信手机号,uniapp,微信小程序获取手机号,java,spring boot,uni-app,微信小程序
java springboot+uniapp实现微信小程序获取微信手机号,uniapp,微信小程序获取手机号,java,spring boot,uni-app,微信小程序

3、查看手机号验证额度

注意:如果按照开头所说,完成小程序备案、微信认证等点击右侧付费管理-》用量统计-》手机号快速验证组件,有标注资源包总量(如下图资源包有1000次体验次数后续可自行加购)。
java springboot+uniapp实现微信小程序获取微信手机号,uniapp,微信小程序获取手机号,java,spring boot,uni-app,微信小程序
java springboot+uniapp实现微信小程序获取微信手机号,uniapp,微信小程序获取手机号,java,spring boot,uni-app,微信小程序

4、在uni-app和微信开发者工具中填写自己第一步获取到的AppId

1、uni-app中
java springboot+uniapp实现微信小程序获取微信手机号,uniapp,微信小程序获取手机号,java,spring boot,uni-app,微信小程序
2、微信开发者工具中
java springboot+uniapp实现微信小程序获取微信手机号,uniapp,微信小程序获取手机号,java,spring boot,uni-app,微信小程序

前端uniapp代码

1、添加获取手机号按钮

因为我们这边需要调用的是手机号所以open-type=getPhoneNumber和@getphonenumber=‘自定义方法’。
@getphonenumber是用户在弹出申请获取用户手机号时用户手动点击了手机号的回调。

<button class="loginPopup-btnList-login" open-type="getPhoneNumber" @getphonenumber="wxPhonelogin">
	微信手机号登录
</button>

2、自定义方法实现

实现思路:
1、先用uni.login返回的用户登录凭证,去后端解析出open_id,如果有存在相应的open_id,则直接返回用户执行登录。
2、如果用户第一次手机号授权登录系统,将微信open_id存入数据库用户表中,返回用户执行登录。
参考uni.login参考文档:uni.login API

async wxPhonelogin(e) {
	const _this = this
	// 开启遮罩层
	_this.showLoadings(true);
	// 调用uni-app提供登录接口 
	uni.login({
		const _this = this
		// 用户点击了允许后操作
		if (e.detail.errMsg == 'getPhoneNumber:ok') {
			// 开启遮罩层
			_this.showLoadings(true);
			uni.login({
				// 登录服务提供商,我们需要微信登录
				provider: "weixin",
				async success(loginRes) {
					// 调用uni-app提供登录接口
					let data = {
						// 用户登录凭证。开发者需要在开发者服务器后台,使用 code 换取 openid 和 session_key 等信息
						code: loginRes.code,
						// 微信授权手机弹窗选择手机后返回code,使用access_token可以解析出手机号
						mobileCode: e.detail.code,
					}
					try {
						// 如果用户表已经存在code对应解析的openId,直接完成登录
						const userOpenIdRes = await openIdLoginApi(data)
						if (userOpenIdRes.success && userOpenIdRes.data !== null) {
							_this.tellPhoneValue = userOpenIdRes.data.account
							// 获取返回数据 执行操作
							_this.loginAfter(userOpenIdRes, 'wxLogin');
							_this.getUserInfo();
						}
						// 关闭遮罩层
						_this.showLoadings(false);
					} catch (e) {
						// 关闭遮罩层
						_this.showLoadings(false);
						// 提示错误信息
						if (e.data.msg) {
							_this.setShowToastFunc(e.data.msg);
						} else {
							_this.setShowToastFunc('登录异常~');
						}

						return;
					}
				}
			})
		} else {
			// 用户点解拒绝后不做操作
			return;
		}
},

3、对应请求接口

import {requestApi} from './requestApi.js';

const url = '/thirdPartyLogin';
// 微信openID登录
function openIdLoginApi(data) {
	return requestApi({
		url: url + '/openIdLogin',
		data: data,
		method: 'POST'
	});
}
export {
	wxLogin,
	openIdLoginApi
}

4、当前效果

正常到这一步,应该点击按钮就会弹出选择手机号
如果未出弹出选择手机号,需要查看控制台报错信息。可能是前期工作未处理好的原因!!
如下效果
微信开发者工具和华为真机效果。
java springboot+uniapp实现微信小程序获取微信手机号,uniapp,微信小程序获取手机号,java,spring boot,uni-app,微信小程序

后端java代码

1、controller

@Api(value = "第三方登录", tags = "第三方登录")
@RestController
@RequestMapping("thirdPartyLogin")
@AllArgsConstructor
public class ThirdPartyLoginController {
    private ThirdPartyLoginService thirdPartyLoginService;

    @PostMapping("/openIdLogin")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "微信OpenId登录", notes = "微信OpenId登录")
    public R<Object> openIdLogin(@RequestBody ThirdPartyWxLoginDto params) {
        AuthInfo authInfo = thirdPartyLoginService.openIdLogin(params);
        Map<String, String> map = new HashMap<>(6);
        map.put("token", authInfo.getAccessToken());
        map.put("userId", authInfo.getUserId().toString());
        map.put("userName", authInfo.getUserName());
        map.put("account", authInfo.getAccount());
        // 手机号脱敏
        String s = authInfo.getPhone().replaceAll("(\\d{3})\\d*(\\d{4})", "$1****$2");
        map.put("userPhone",s);
        return R.data(map);
    }
}

2、service

public interface ThirdPartyLoginService {
    AuthInfo openIdLogin(ThirdPartyWxLoginDto params);
}

3、实现类

代码中用到了restTemplate做请求,需要引入相关依赖和配置。请自行百度。
用到的API
(1)用户手机号验证 :手机号快速验证
(2)第一步用户手机号验证调用需要带参ACCESS_TOKEN:获取接口调用凭据
(3)根据用户uni.login获取到的登录凭证code解析出open_id :小程序登录文章来源地址https://www.toymoban.com/news/detail-782428.html

@Service
@Slf4j
public class ThirdPartyLoginServiceImpl implements ThirdPartyLoginService {
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private IUserService iUserService;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private IDhMessagePushService iDhMessagePushService;
    /**获取手机号*/
    public static final String WX_GET_PHONE_NUMBER_URL = "https://api.weixin.qq.com/wxa/business/getuserphonenumber";

    /**获取接口调用凭据,需要此凭据解析手机号*/
    public static final String WX_ACCESE_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";
    /*** 获取open_id接口*/
    public static final String OPEN_ID_URL = "https://api.weixin.qq.com/sns/jscode2session";

    @Value("${wx.config.appSecret}")
    private String appSecret;
    @Value("${wx.config.appId}")
    private String appId;

    public static final String REDIS_KEY_ACCESS_TOKEN = "REDIS_KEY_ACCESS_TOKEN";
	/**
	*	微信openID验证登录,如果用户表有openId直接验证登录,否则走微信手机号验证登录
	*/
	@Override
    public AuthInfo openIdLogin(ThirdPartyWxLoginDto params) {
        // 获取用户openId,判断数据库是否有存入该openId了,如果有代表之前登录过了就不用走手机验证
        HashMap<String, String> userOpenId = getUserOpenId(params);
        String openid = userOpenId.get("openid");
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.lambda().eq(User::getOpenId,openid);
        List<User> list = iUserService.list(userQueryWrapper);
        if (CollectionUtil.isNotEmpty(list)) {
            if (list.size() > 1) {
                // 如果有多个则微信授权找到手机号进行登录
                return wxLogin(params.getMobileCode(),openid);
            } else {
                // 如果只有一个则判断 用户是否失效,若正常则返回
                User user = list.get(0);
                if (Objects.nonNull(user.getFailureTime())) {
                    throw new RuntimeException("当前手机号已失效无权限登录~");
                }
                UserInfo userInfo = getUserInfo(user);
                return TokenUtil.createAuthInfo(userInfo);
            }
        }
        // 如果为空则微信授权登录
        return wxLogin(params.getMobileCode(),openid);
    }
    /**
	*	微信手机号验证登录
	*/
    private AuthInfo wxLogin(String mobileCode , String openid) {
        log.info("=== 微信手机授权登录开始 ===");
        String purePhoneNumber = getWxUserPhone(mobileCode);
        // 根据手机号查询用户表 判断是否有该手机号如果没有的话则 不允许登录
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.lambda().eq(User::getAccount,purePhoneNumber);
        User user = iUserService.getOne(userQueryWrapper);
        if (Objects.isNull(user) || Objects.nonNull(user.getFailureTime())) {
            throw new RuntimeException("当前手机号无系统权限或者已失效~");
        }
        user.setOpenId(openid);
        user.setPhone(purePhoneNumber);
        iUserService.saveOrUpdate(user);
        // 封装返回数据
        UserInfo userInfo = getUserInfo(user);
        return TokenUtil.createAuthInfo(userInfo);
    }
    /**
	*	解析用户手机号
	*/
    private String getWxUserPhone(String mobileCode) {
        // 获取Access_Token
        String accessToken = getAccessToken();
        // 请求解析手机号
        StringBuilder getPhoneNumberUrl = new StringBuilder(WX_GET_PHONE_NUMBER_URL);
        getPhoneNumberUrl.append("?access_token=").append(accessToken);
        Map<String, String> phoneNumberParam = new HashMap<>();
        phoneNumberParam.put("code", mobileCode);
        ResponseEntity<HashMap> hashMapResponseEntity = restTemplate.postForEntity(getPhoneNumberUrl.toString(), phoneNumberParam, HashMap.class);
        if (hashMapResponseEntity.getStatusCodeValue() != 200 || Objects.isNull(hashMapResponseEntity.getBody()) || (Integer) hashMapResponseEntity.getBody().get("errcode")!=0) {
            throw new RuntimeException("解析手机接口调用异常~");
        }
        log.info("=== 微信手机授权请求解析手机号返回:{} ",hashMapResponseEntity.getBody());
        LinkedHashMap phoneInfo = (LinkedHashMap)hashMapResponseEntity.getBody().get("phone_info");
        String purePhoneNumber = (String)phoneInfo.get("purePhoneNumber");
        return purePhoneNumber;
    }
    /**
	*	获取Access_Token,消息订阅或者微信授权都需要这个东西,可以放入缓存因为每次获取都有两个小时有效期
	*/
    private String getAccessToken() {
        // 查询redis 是否有存放access_token避免过多次请求
        Object redisRes = redisUtil.get(REDIS_KEY_ACCESS_TOKEN);
        if (Objects.nonNull(redisRes)) {
            return redisRes.toString();
        }
        // 请求ACCESS_TOKEN
        StringBuilder accessTokenUrl = new StringBuilder(WX_ACCESE_TOKEN_URL);
        accessTokenUrl.append("?grant_type=client_credential");
        accessTokenUrl.append("&appid=").append(appId);
        accessTokenUrl.append("&secret=").append(appSecret);
        ResponseEntity<HashMap> accessTokenRes = restTemplate.getForEntity(accessTokenUrl.toString(), HashMap.class);
        if (accessTokenRes.getStatusCodeValue() != 200 || Objects.isNull(accessTokenRes.getBody()) || Objects.nonNull(accessTokenRes.getBody().get("errcode"))) {
            throw new RuntimeException("Token接口调用异常~");
        }
        log.info("=== 微信手机授权请求AccessToken返回:{} ",accessTokenRes.getBody());
        String accessToken = accessTokenRes.getBody().get("access_token").toString();
        // 存放redis 设置两个小时超时时间
        redisUtil.set(REDIS_KEY_ACCESS_TOKEN,accessToken,2L, TimeUnit.HOURS);
        return accessToken;
    }
    /**
	*	获取用户OpenId
	*/
    private HashMap<String, String> getUserOpenId(ThirdPartyWxLoginDto params) {
        StringBuilder openIdUrl = new StringBuilder(OPEN_ID_URL);
        openIdUrl.append("?grant_type=").append("authorization_code");
        openIdUrl.append("&appid=").append(appId);
        openIdUrl.append("&secret=").append(appSecret);
        openIdUrl.append("&js_code=").append(params.getCode());
        ResponseEntity<String> openIdRes = restTemplate.getForEntity(openIdUrl.toString(), String.class);
        if (openIdRes.getStatusCodeValue() != 200 || Objects.isNull(openIdRes.getBody())) {
            throw new RuntimeException("OpenId接口调用异常~");
        }
        HashMap<String,String> parse = JSON.parseObject(openIdRes.getBody(),HashMap.class);
        if (Objects.nonNull(parse.get("errcode"))) {
            throw new RuntimeException("OpenId接口调用异常~");
        }
        return parse;
    }
}

4、实体类

@Data
public class ThirdPartyWxLoginDto {
    /**
     * 用户uni.login登录凭证code
     * */
    private String code;
    /**
     * 手机号Code
     * */
    private String mobileCode;
}

希望对你有所帮助,谢谢阅读!如果代码有哪些地方有错误或者能改进欢迎评论留言。

到了这里,关于java springboot+uniapp实现微信小程序获取微信手机号的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot整合微信小程序登录获取手机号并解密

    SpringBoot+微信小程序  文章目录: 一、小程序登录获取手机号的流程 二、pom导入所需的依赖包 三、接收微信小程序的参数 四、后端发请求的util工具方法 五、获取手机号的接口 六、请求接口获取的phone_info信息 1.前端请求getPhoneNumber方法获取code传给后端接口; 2.后端接口通过

    2024年02月09日
    浏览(41)
  • UNIAPP---实现微信小程序登录授权和手机号授权(uniapp做微信小程序)

    描述:uniapp开发小程序,先授权用户信息后再出现手机号授权的页面进行手机号授权。完成后返回上一页面并把信息存入后台以及前台缓存中,方便使用。 1.在uniapp的manifest.json进行微信小程序配置 2.封装request请求api.js(如果已封装可跳过) 3.封装微信授权登录以及获取手机

    2024年02月11日
    浏览(32)
  • 微信小程序获取手机号登录(Java后端)

    1.前端请求getPhoneNumber方法获取code传给后端接口; 2.后端接口通过配置的appid、secretKey请求接口https://api.weixin.qq.com/cgi-bin/token获取access_token参数; 3.后端通过参数code和参数access_token,去请求接口https://api.weixin.qq.com/wxa/business/getuserphonenumber来获取手机号。

    2024年02月11日
    浏览(52)
  • 微信小程序——获取用户手机号(Java后台)

    最后有完整代码 1、获取code 2、利用code获取sessionkey 小程序端: Java后台: 获取小程序密钥:微信公众平台-开发管理-开发设置 3、获取iv和encryptedData并解密获取手机号 java后台: 如果报错40029则可能是appid不对 4、完整代码 wxml: wxss: js: Java后台

    2024年02月12日
    浏览(44)
  • 【微信小程序】实现微信小程序登录(附源码)后端,微信小程序获取手机号

    登录简介 第一步:获取token 第二步:通过token拿用户信息 第三步:调用接口获取手机号 HttpClientUtil: WeChatUtil: controller层: service层: serviceImpl层: 登录简介        新版本微信小程序登录 是前端获取用户信息,不再是后端获取信息进行保存。所以后端要做的主要流程就是

    2024年04月23日
    浏览(40)
  • uniapp 实现微信小程序手机号一键登录

    app 和 h5 手机号一键登录,参考文档:uni-app官网 以下是uniapp 实现微信小程序手机号一键登录 1、布局

    2024年02月03日
    浏览(43)
  • Taro:微信小程序通过获取手机号实现一键登录

            本文介绍如果通过微信小程序的getPhoneNumber方法获取用户微信绑定的手机号并自动注册登录。 1、按钮类型 openType 指定 \\\"getPhoneNumber\\\"   2、@getphonenumber必须全部小写 code:手机号获取凭证:动态令牌。可通过动态令牌换取用户手机号。         后台根据前端传入

    2024年02月16日
    浏览(38)
  • 微信小程序 - 实现手机号登录--授权并获取手机号保存至本地

    微信官方文档 | 获取手机号 这是服务端的  这是我们前端获取手机号需要给接口传递的两个参数    注意: 参数一: 获取access_token需要用到小程序密钥,这个需要从 服务端获取 ,也就是需要请求后端接口获取access_token,千万不要将小程序密钥写在前端代码中, 必须 要从服

    2024年02月03日
    浏览(44)
  • Java获取微信小程序code获取openid、session_key、unionid,获取授权信息解密获取手机号

    WechatUtils (具体实体类自己根据自己的业务需求配置就行) service impl实现类 👆这个代码已经可以解析出code信息,具体的业务流程自己去添加就ok 还是我们之前的WechatUtils,在里面添加getPhone方法 service impl实现类 👆以上就是本次的笔记了,大家有需要用的自取,有用记得点个赞

    2024年02月16日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包