微信小程序获取手机号
在微信小程序开发中,获取用户手机号是实现登录、绑定账号等核心功能的关键环节。微信官方对手机号获取的规则和接口一直在迭代优化,2026 年最新版本中,核心逻辑围绕「手机号快捷登录组件」展开,同时强化了隐私授权和安全校验要求。本文将从规则解读、实战开发、避坑指南三个维度,带你掌握最新的手机号获取方案。
button组件open-type="getPhoneNumber"仍可用,但返回参数格式优化,不再返回iv和encryptedData,而是直接返回code(手机号凭证);wx-phone-number,支持更友好的授权弹窗,且降低了接口调用频率限制;weixin-java-miniapp 4.0+(Java)/ wechatpy 2.9+(Python)SDK,旧版解密方式已废弃;code有效期为 5 分钟,且仅能使用 1 次,超时或重复使用会返回40001错误。2.30.0+(建议在小程序配置中设置最低基础库版本);code;code传给后端服务器;html
预览
<!-- pages/login/login.wxml -->
<view class="container">
<!-- 隐私授权提示(必须) -->
<view class="privacy-tip">
点击「获取手机号」即表示同意《隐私政策》,我们将仅用于账号登录验证
</view>
<!-- 手机号授权按钮 -->
<button
open-type="getPhoneNumber"
bindgetphonenumber="getPhoneNumber"
type="primary"
class="btn"
>
获取手机号快捷登录
</button>
</view>
javascript
运行
// pages/login/login.js
Page({
// 获取手机号回调
getPhoneNumber(e) {
// 1. 判断用户是否授权
if (e.detail.errMsg === 'getPhoneNumber:fail user deny') {
wx.showToast({
title: '您拒绝了手机号授权',
icon: 'none'
});
return;
}
// 2. 获取手机号code(2026年核心参数)
const code = e.detail.code;
if (!code) {
wx.showToast({
title: '授权失败,请重试',
icon: 'none'
});
return;
}
// 3. 获取登录态code(需先调用wx.login)
wx.login({
success: (res) => {
const loginCode = res.code;
// 4. 调用后端接口,传递code和loginCode
wx.request({
url: 'https://your-domain.com/api/getPhone', // 后端接口地址
method: 'POST',
data: {
phoneCode: code,
loginCode: loginCode
},
success: (response) => {
if (response.data.code === 0) {
// 成功获取手机号,完成登录逻辑
const phoneNumber = response.data.data.phone;
wx.setStorageSync('phone', phoneNumber);
wx.showToast({
title: '登录成功',
icon: 'success'
});
// 跳转到首页
wx.switchTab({
url: '/pages/index/index'
});
} else {
wx.showToast({
title: response.data.msg || '登录失败',
icon: 'none'
});
}
},
fail: (err) => {
wx.showToast({
title: '网络错误,请重试',
icon: 'none'
});
console.error('请求失败:', err);
}
});
},
fail: (err) => {
wx.showToast({
title: '获取登录态失败',
icon: 'none'
});
console.error('wx.login失败:', err);
}
});
}
});
html
预览
<!-- pages/login/login.wxml -->
<wx-phone-number
bind:phonenumberget="onPhoneNumberGet"
placeholder="请绑定手机号"
>
<button type="primary" class="btn">手机号快捷登录</button>
</wx-phone-number>
javascript
运行
// pages/login/login.js
Page({
onPhoneNumberGet(e) {
// 逻辑与方式1一致,仅事件名不同
if (e.detail.errMsg === 'phonenumberget:fail user deny') {
wx.showToast({ title: '您拒绝了手机号授权', icon: 'none' });
return;
}
const code = e.detail.code;
// 后续逻辑同方式1...
}
});
xml
<!-- 微信小程序SDK(2026最新版) -->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-miniapp</artifactId>
<version>4.5.0</version>
</dependency>
java
运行
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.miniapp.api.WxMaService;
import me.chanjar.weixin.miniapp.api.impl.WxMaServiceImpl;
import me.chanjar.weixin.miniapp.bean.WxMaJscode2SessionResult;
import me.chanjar.weixin.miniapp.bean.WxMaPhoneNumberInfo;
import me.chanjar.weixin.miniapp.config.impl.WxMaDefaultConfigImpl;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
public class PhoneController {
// 小程序配置(建议从配置文件读取)
private static final String APP_ID = "你的小程序AppId";
private static final String APP_SECRET = "你的小程序AppSecret";
// 初始化WxMaService
private WxMaService getWxMaService() {
WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
config.setAppid(APP_ID);
config.setSecret(APP_SECRET);
WxMaService service = new WxMaServiceImpl();
service.setWxMaConfig(config);
return service;
}
/**
* 获取手机号接口
*/
@PostMapping("/api/getPhone")
public Map<String, Object> getPhone(@RequestBody Map<String, String> params) {
String phoneCode = params.get("phoneCode");
String loginCode = params.get("loginCode");
// 1. 校验参数
if (phoneCode == null || loginCode == null) {
return Map.of("code", -1, "msg", "参数不能为空");
}
WxMaService wxMaService = getWxMaService();
try {
// 2. 先通过loginCode获取openid(可选,用于关联用户)
WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(loginCode);
String openid = session.getOpenid();
// 3. 调用微信接口换取手机号(2026核心API)
WxMaPhoneNumberInfo phoneInfo = wxMaService.getUserService().getPhoneNoInfo(phoneCode);
String phoneNumber = phoneInfo.getPhoneNumber(); // 用户手机号
// 4. 业务逻辑:保存手机号、生成token等
// ...(此处省略你的业务代码)
// 5. 返回结果
return Map.of(
"code", 0,
"msg", "success",
"data", Map.of("phone", phoneNumber, "openid", openid)
);
} catch (WxErrorException e) {
// 处理异常(如code过期、无效等)
return Map.of("code", -1, "msg", "获取手机号失败:" + e.getError().getErrorMsg());
} catch (Exception e) {
return Map.of("code", -1, "msg", "服务器异常");
}
}
}
code;code(手机号凭证)替换旧版的加密数据,流程更简洁、安全;code,后端调用微信官方 SDK 换取手机号;转自https://blog.csdn.net/2503_92319969/article/details/157353067