1
0
mirror of synced 2026-10-19 05:56:26 +08:00

🎨 #4078 【小程序】获取手机号的方法支持openid校验

This commit is contained in:
Binary Wang
2026-07-31 00:17:22 +08:00
committed by GitHub
parent 8c5d917db9
commit bdf947e2ca
6 changed files with 87 additions and 3 deletions

View File

@@ -73,6 +73,19 @@ public interface WxMaUserService {
*/
WxMaPhoneNumberInfo getPhoneNumber(String code) throws WxErrorException;
/**
* 获取手机号信息,并校验手机号获取凭证与用户的绑定关系。
*
* @param code 每个code只能使用一次,code的有效期为5min。code获取方式参考<a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html">手机号快速验证组件</a>
* @param openid 用户openid,传入后微信服务端将校验其与code的绑定关系
* @return 用户手机号信息
* @throws WxErrorException .
* @apiNote 该接口用于将code换取用户手机号。
*/
default WxMaPhoneNumberInfo getPhoneNumber(String code, String openid) throws WxErrorException {
return this.getPhoneNumber(code);
}
/**
* 获取手机号信息,基础库:2.21.2及以上或2023年8月28日起
*

View File

@@ -374,7 +374,7 @@ public abstract class BaseWxMaServiceImpl<H, P> implements WxMaService, RequestH
Map<String, String> headers,
String data)
throws WxErrorException {
String dataForLog = "Headers: " + headers.toString() + " Body: " + data;
String dataForLog = "Headers: " + headers.toString() + " Body: " + DataUtils.handleDataWithSecret(data);
return executeWithRetry(
(uriWithAccessToken) -> executor.execute(uriWithAccessToken, headers, data, WxType.MiniApp),
uri,

View File

@@ -16,6 +16,7 @@ import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.SignUtils;
import me.chanjar.weixin.common.util.json.GsonParser;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.Map;
@@ -67,8 +68,16 @@ public class WxMaUserServiceImpl implements WxMaUserService {
@Override
public WxMaPhoneNumberInfo getPhoneNumber(String code) throws WxErrorException {
return this.getPhoneNumber(code, null);
}
@Override
public WxMaPhoneNumberInfo getPhoneNumber(String code, String openid) throws WxErrorException {
JsonObject param = new JsonObject();
param.addProperty("code", code);
if (StringUtils.isNotBlank(openid)) {
param.addProperty("openid", openid);
}
String responseContent = this.service.post(GET_PHONE_NUMBER_URL, param.toString());
JsonObject response = GsonParser.parse(responseContent);
if (response.has(PHONE_INFO)) {

View File

@@ -0,0 +1,50 @@
package cn.binarywang.wx.miniapp.api.impl;
import cn.binarywang.wx.miniapp.api.WxMaService;
import com.google.gson.JsonObject;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.json.GsonParser;
import org.mockito.ArgumentCaptor;
import org.testng.annotations.Test;
import static cn.binarywang.wx.miniapp.constant.WxMaApiUrlConstants.User.GET_PHONE_NUMBER_URL;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
/**
* {@link WxMaUserServiceImpl} 获取手机号接口的单元测试。
*/
public class WxMaUserServiceImplPhoneNumberTest {
@Test
public void shouldSendOpenidWhenGettingPhoneNumber() throws WxErrorException {
WxMaService wxMaService = mock(WxMaService.class);
when(wxMaService.post(anyString(), anyString())).thenReturn("{\"phone_info\":{}}");
new WxMaUserServiceImpl(wxMaService).getPhoneNumber("phone-code", "user-openid");
ArgumentCaptor<String> requestBody = ArgumentCaptor.forClass(String.class);
verify(wxMaService).post(eq(GET_PHONE_NUMBER_URL), requestBody.capture());
JsonObject request = GsonParser.parse(requestBody.getValue());
assertEquals(request.get("code").getAsString(), "phone-code");
assertEquals(request.get("openid").getAsString(), "user-openid");
}
@Test
public void shouldIgnoreBlankOpenidWhenGettingPhoneNumber() throws WxErrorException {
WxMaService wxMaService = mock(WxMaService.class);
when(wxMaService.post(anyString(), anyString())).thenReturn("{\"phone_info\":{}}");
new WxMaUserServiceImpl(wxMaService).getPhoneNumber("phone-code", " ");
ArgumentCaptor<String> requestBody = ArgumentCaptor.forClass(String.class);
verify(wxMaService).post(eq(GET_PHONE_NUMBER_URL), requestBody.capture());
JsonObject request = GsonParser.parse(requestBody.getValue());
assertFalse(request.has("openid"));
}
}