官方文档
获取手机号 | 微信开放文档 (客户端)
后端 API | 微信开放文档(服务端)
接口入参
目前该接口针对非个人开发者,且完成了认证的小程序开放(不包含海外主体)。需谨慎使用,若用户举报较多或被发现在不必要场景下使用,微信有权永久回收该小程序的该接口权限;
在使用该接口时,用户可使用微信绑定手机号进行授权,也添加非微信绑定手机号进行授权。若开发者仅通过手机号作为业务关联凭证,在重点场景可适当增加短信验证逻辑。
代码示例
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"></button>
Page({
getPhoneNumber (e) {
console.log(e.detail.code)
}
})
完整演示
<template>
<view class="flex">
<view class="title">
<view class="logo">
<image src="/static/image/logo.png" mode="widthFix" />
</view>
</view>
<!-- 手机号登录 --授权并获取手机号保存至本地 -->
<button
type="default"
class="loginButton"
open-type="getPhoneNumber"
@getphonenumber="getPhoneNumber"
>
<view class="row">
<view class="icon">
<u-icon name="weixin-fill" size="28"></u-icon>
</view>
<view style="font-size: 30rpx">微信登录</view>
</view>
</button>
<!-- 协议选择 -->
<view class="serve-rule">
<u-checkbox-group size="24" @click="changeCheckStatus">
<u-checkbox
class="checkbox"
v-model="checkStatus"
activeColor="#ff414e"
></u-checkbox>
</u-checkbox-group>
<view class="protocol-prompt">
<text @click="changeCheckStatus">本人理解并同意</text>
<text class="serve-label" @click.stop="onServiceAgreement"
>《隐私政策》</text
>
<text class="serve-label" @click.stop="onUserAgreement"
>《用户协议》</text
>
</view>
</view>
<u-toast ref="uToast" />
</view>
</template>
<script>
export default {
name: "login",
data() {
return {
phoneCode: "", // 获取手机号使用的code
phoneNumber: "", // 手机号
access_token: "", // 用户token
code: "", // authCode用户code码 ---- 登陆使用的code
userInfo: "", //用户信息
id: "",
checkStatus: false, //协议是否勾选
};
},
onLoad(options) {
const version = wx.getSystemInfoSync().SDKVersion;
console.log("当前版本号version", version);
if (this.compareVersion(version, "2.21.2") >= 0) {
uni.removeStorageSync("storage_USERPHONE");
this.getWxCode(); // 获取微信用户code码--登录使用
this.getAccessToken(); // 获取 accessToken --获取手机号使用
} else {
// 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
wx.showModal({
title: "提示",
content:
"当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。",
});
}
},
methods: {
// 获取微信用户code码--登录使用
async getWxCode() {
const result = await wx.login();
// console.log(result);
if (result.code) {
this.code = result.code;
console.log("登录使用的code =====>>>>>>", this.code);
}
},
// 获取 accessToken 注意:要从服务端获取,密钥不能写在前端。 --获取手机号使用
getAccessToken() {
this.$http.getAccessToken().then((res) => {
if (res.success) {
let resObj = res.datas && res.datas.obj;
console.log("resObj======>>>>>>", resObj);
this.access_token = resObj.access_token;
console.log("that.access_token======>>>>>>", this.access_token);
}
});
},
// 低版本兼容处理方法封装
compareVersion(v1, v2) {
v1 = v1.split(".");
v2 = v2.split(".");
const len = Math.max(v1.length, v2.length);
while (v1.length < len) {
v1.push("0");
}
while (v2.length < len) {
v2.push("0");
}
for (let i = 0; i < len; i++) {
const num1 = parseInt(v1[i]);
const num2 = parseInt(v2[i]);
if (num1 > num2) {
return 1;
} else if (num1 < num2) {
return -1;
}
}
return 0;
},
// 获取用户手机号-接口
getUserPhone() {
this.$http
.getPhone({
code: this.phoneCode,
access_token: this.access_token,
})
.then((res) => {
// console.log("用户手机号res====>",res)
if (res.success) {
let resDatas = res.datas;
let phoneInfo = JSON.parse(resDatas.phone_info);
// console.log("获取到的用户手机号相关信息=====>>>>>>", phoneInfo)
this.phoneNumber = phoneInfo.phoneNumber;
console.log("获取到的用户手机号=====>>>>>>", this.phoneNumber);
uni.setStorageSync("storage_USERPHONE", this.phoneNumber);
this.login();
}
});
},
// 获取手机号的code并授权
getPhoneNumber(e) {
console.log("e=====>>>>>>", e);
if (this.checkStatus) {
let detail = e.detail;
if (detail.errMsg === "getPhoneNumber:ok") {
let that = this;
this.phoneCode = detail.code;
console.log("获取手机号使用的code =====>>>>>>", this.phoneCode);
if (this.phoneCode) {
this.getUserPhone();
} else {
this.login();
}
} else {
console.log("取消授权!");
}
} else {
uni.showToast({
icon: "none",
title: "请阅读并确认隐私政策和用户协议",
});
}
},
// 登录
async login() {
uni.showLoading({
title: "登录中.....",
mask: true,
});
const res = await this.$http.wxLogin({
code: this.code,
udid: "**************",
appletType: 4,
});
if (res.success) {
if (res.datas.token) {
uni.setStorageSync("ticket", res.datas.token);
}
if (res.datas.obj) {
uni.setStorageSync("userInfo", res.datas.obj);
this.id = res.datas.obj.extInfo.id;
}
this.getAppletVersion();
return;
}
},
getAppletVersion() {
uni.hideLoading();
uni.reLaunch({
url: `/pages/index/index`,
});
},
// 切换是否选中复选框
changeCheckStatus() {
this.checkStatus = !this.checkStatus;
},
// 进入《隐私政策》
onServiceAgreement() {
uni.navigateTo({
url: "/pages/privacy-policy/privacy-policy",
fail(e) {
console.log(e);
},
});
},
// 《用户协议》
onUserAgreement() {
uni.navigateTo({
url: "/pages/user-service-agreement/user-service-agreement",
fail(e) {
console.log(e);
},
});
},
},
};
</script>
<style lang="scss" scoped>
.flex{display:flex;flex-flow:column nowrap;justify-content:flex-start;align-items:center;position:fixed;width:100vw;height:100vh;top:200rpx;left:0;padding:0 64rpx;.title{display:flex;flex-direction:column;align-items:center;margin-bottom:200rpx;width:240rpx;.logo{width:360rpx;height:360rpx;overflow:hidden;image{width:100%;height:auto}
text{display:inline-block;color:#404040}
}}.loginButton{width:100%;height:72rpx;background:linear-gradient(142deg,#ff8677 11%,#ff424e 94%);border-radius:88rpx;font-size:32rpx;font-family:PingFangSC,PingFangSC-Medium;font-weight:500;text-align:center;line-height:52rpx;color:#ffffff;letter-spacing:2rpx;margin-bottom:52rpx}
.serve-rule{width:100%;margin-left:16rpx;display:flex;align-items:center;position:relative;.serve-label{color:#ff414e;// transform:translateX(-10%)}
.protocol-prompt{display:inline-block;position:absolute;left:34rpx}
}.checkbox{margin-right:0}
.row{padding:10rpx;flex-flow:row nowrap;display:flex;justify-content:center;align-items:center;.icon-text{color:#007aff}
}.ding-row{flex-flow:row nowrap;display:flex;justify-content:center;align-items:center;.icon-text{color:#007aff}
}.icon{margin-right:10rpx;display:flex;align-items:center}
.btn{width:90%;overflow:hidden;text-align:center}
}
</style>