微信小程序开发笔记 进阶篇⑤——getPhoneNumber 获取用户手机号码(基础库 2.21.2 之前)

news2024/11/17 15:33:23

文章目录

  • 一、前言
  • 二、前端代码wxml
  • 三、前端代码js
  • 四、后端java
  • 五、程序流程
  • 六、参考

一、前言

  • 大部分微信小程序开发者都会有这样的需求:获取小程序用户的手机号码
  • 但是,因为小程序用户的手机号码属于重要信息,为了安全,所以需要如下一系列较为复杂的方法和步骤。
  • 我前期主要通过小程序云的方法获取用户手机号码,后面因为微信政策变更,小程序云不再提供免费版本,最低每月也要收费19元
  • 所以,我才转用方法二和方法三。否则方法一小程序云的方法是最简单的。

微信小程序开发笔记 进阶篇④——getPhoneNumber 获取用户手机号码(小程序云)
微信小程序开发笔记 进阶篇⑤——getPhoneNumber 获取用户手机号码(基础库 2.21.2 之前)
微信小程序开发笔记 进阶篇⑥——getPhoneNumber 获取用户手机号码(基础库 2.21.2 之后)

  • 首先确保基础库版本在2.21.2之前

在这里插入图片描述

二、前端代码wxml

  • 必须要有这个button,并且用户点击了,才能有下一步
<button type="default" open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber" class="weui-vcode-btn" wx:else>获取手机号</button>

在这里插入图片描述

三、前端代码js

  • 定义一个code全局变量
var code = ""
  • 该界面onShow的时候,调用wx.login函数获取code
  • 这边这里有个风险,这个code存在有效期,到你用的时候可能会过期

onShow() {        
    wx.login({
        success: function (res) {
            console.log("wx.login success", res)
            if (res.code) {    
                code = res.code
            } else {
                _this.showToast('失败!' + res.errMsg)
            }
        },
        fail: function (res) {
            console.log('wx.login fail' + res)
        }
    })
},
  • bindgetphonenumber="getPhoneNumber"按钮的回调函数
getPhoneNumber(e) {
    var _this = this
    console.log("getPhoneNumber", e)
    
    keyueliSdk.getPhoneNumber({
        code: code,
        encryptedData: e.detail.encryptedData,
        iv: e.detail.iv,
        appId: app.globalData.appId,
    },
    (res) => {
        console.log("getPhoneNumber", "success", res)
        _this.setData({
            mobile: res.data.data.phoneNumber
        })
    },
    (res) => {
        console.log("getPhoneNumber", "fail", res)
    })
},
  • keyueliSdk.js接口工具类
//获取用户手机号码
const getPhoneNumber = (data, success, fail) => {
  console.log("getPhoneNumber", data)
  request(
    endpoint + "/v1/app/user/getPhoneNumber", {
      // 'content-type': 'application/x-www-form-urlencoded'
      'content-type': 'application/json'
    },
    data,
    "POST",
    success, fail
  )
}

module.exports = {
  getPhoneNumber: getPhoneNumber,
}

四、后端java

  • controller.java
@ApiOperation("查询用户手机号码")
@PostMapping("/getPhoneNumber")
public AjaxResult getPhoneNumber(@ApiParam() @RequestBody AppCode appCode)
{
    log.info(appCode.toString());
    return AjaxResult.success(loginService.getPhoneNumber(appCode));
}
  • loginService.java
public JSONObject getPhoneNumber(AppCode appCode){
    if(!WXUtils.checkAppId(appCode.getAppId())){
        log.error("appId异常: "+ appCode.toString());
        throw new CustomException("AppId 异常");
    }

    JSONObject codeData = WXUtils.codeAnalysis(appCode.getCode(), appCode.getAppId());
    if(ObjectUtil.isNull(codeData)){
        log.error("code异常: "+ appCode.toString());
        throw new CustomException("code 异常");
    }
    String sessionKey = codeData.getString("session_key");
    String openId = codeData.getString("openid");
    String unionId = codeData.getString("unionid");

    JSONObject decryptObject = WXUtils.decrypt(appCode.getAppId(), appCode.getEncryptedData(), sessionKey, appCode.getIv());
    if(ObjectUtil.isNull(decryptObject)){
        log.error("encryptedData异常: "+ appCode.toString());
        throw new CustomException("encryptedData 异常");
    }
    log.info(decryptObject.toJSONString());

    return decryptObject;
}
  • WXUtils.java
/**
 * 解密数据
 * @return
 * @throws Exception
 */
public static JSONObject decrypt(String appId, String encryptedData, String sessionKey, String iv){
    try {
        byte[] resultByte = AESUtils.decrypt(Base64.decodeBase64(encryptedData),Base64.decodeBase64(sessionKey),Base64.decodeBase64(iv));
        if(null != resultByte && resultByte.length > 0){
            String result = new String(WxPKCS7Encoder.decode(resultByte));
            JSONObject jsonObject = JSONObject.parseObject(result);
            String decryptAppId = jsonObject.getJSONObject("watermark").getString("appid");
            if(!appId.equals(decryptAppId)){
                return null;
            }
            return jsonObject;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

/**
 * 获取session_key
 * @return
 * @throws Exception
 */
public static JSONObject codeAnalysis(String code, String appId) {
    try {
        String objectStr = HttpUtil.get(String.format("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
                appId, getAppSecret(appId), code));
        log.info(objectStr);
        JSONObject jsonObject = JSON.parseObject(objectStr);
        return jsonObject;
    }catch (Exception e){
        e.printStackTrace();
        log.error("微信code解析异常", e.getMessage());
    }
    return null;
}
  • AESUtils.java
/**
 * AES解密
 *
 * @param content
 *            密文
 * @return
 * @throws InvalidAlgorithmParameterException
 * @throws NoSuchProviderException
 */
public static byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException {
    initialize();
    try {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
        Key sKeySpec = new SecretKeySpec(keyByte, "AES");
        cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化
        byte[] result = cipher.doFinal(content);
        return result;
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    } catch (NoSuchProviderException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}

五、程序流程

注册界面 后端服务器 onShow函数,wx.login获取用户code 按钮点击,getPhoneNumber获取encryptedData和iv https post请求,code/encryptedData/iv/appId等4个参数 拿code和appId通过auth.code2Session获取session_key 密文:Base64_Decode(encryptedData) 秘钥:Base64_Decode(session_key) 初始向量:Base64_Decode(iv) AES-128-CBC 解密,返回phoneNumber 注册界面 后端服务器

六、参考

  • auth.code2Session
  • 开放数据校验与解密
  • 高端帖:手机号解密失败?扫盲帖+解决方案

觉得好,就一键三连呗(点赞+收藏+关注)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/70550.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]Python计算机毕业设计SSM基于智能推荐的胖达大码服装定制网(程序+LW)

[附源码]Python计算机毕业设计SSM基于智能推荐的胖达大码服装定制网&#xff08;程序LW) 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xf…

MacOS卸载自带软件

解锁系统SIP 按CommandR重启电脑&#xff0c;进入后点击上方的实用工具-终端在弹出的终端窗口中输入 csrutil disable下方提示 Successfully&#xff0c;表示解锁成功输入 reboot 重启电脑 卸载自带软件 重启电脑后&#xff0c;打开终端输入sudo -i输入管理员密码分别输入以…

来面试测试岗就这么简单9道题,我刷掉了90%的软件测试员。

人往高处走水往低处流&#xff0c;今天已经是十二月了&#xff0c;“金三银四”招聘季还会远吗&#xff1f; 远观2021年的招聘季&#xff0c;在资本寒冬的映照下&#xff0c;的确萧条了不少&#xff0c;年底裁员、取消年终奖、末尾淘汰制等热门制度&#xff0c;让很多人陷入了…

【与达梦同行】那些DMHS使用二三事

一什么时候用DMHS&#xff1f; Dmhs是异构环境下的数据库实时同步系统。主机源数据库支持 DM6、DM7、MYSQL、PostgreSQL、DB2、SQLServer 和 Oracle9i 以上版本。备机目的数据库支持可通过 ODBC 接口连接的各种主流关系数据库管理系统&#xff0c;包括 DM6、DM7、MYSQL、Postg…

m基于FPGA的积分梳状CIC滤波器verilog设计

目录 1.算法描述 2.仿真效果预览 3.verilog核心程序 4.完整FPGA 1.算法描述 积分梳状滤波器&#xff0c;是指该滤波器的冲激响应具有如下形式&#xff1a; 其物理框图如图所示&#xff1a; 可见&#xff0c;CIC滤波器是由两部分组成&#xff1a;累积器H1和H2梳状滤波器的级…

(附源码)ssm某村青年人口信息管理系统 毕业设计 271621

ssm某村青年人口信息管理系统 摘 要 随着社会的发展&#xff0c;社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用SSM技术和mysql数据库来完…

Python下的Logistic回归模型

以前都是写杂文&#xff0c;今天也写写专业文章。 不讲理论&#xff0c;Logistic回归模型&#xff08;中文简称逻辑回归&#xff09;的形式就是&#xff1a; 其中&#xff0c; 有的人会把Logistic回归模型的形式写成&#xff1a; 其实&#xff0c;它和第一个公式没有区别&…

worldview卫星数据的查询方法

地理遥感生态网平台代理worldview1、worldview2、worldview3、worldview4、quickbird、geoeye、ikonos、 pleiades、spot1、spot2、spot3、spot4、spot5、spot6、spot7、landsat5(tm)、landsat(etm)、landsat8、rapideye、alos、aster、Hyperion(EO-1)、kompsat2、kompsat-3、k…

vue element 动态增加表单并进行表单验证

表单验证: 需要注意的一点是: 普通表单验证单项依靠的是prop…而动态生成的表单要用:prop 书写的语法是:prop=“‘cloudAccounts.’ + index +’.objectDetails’”,cloudAccounts是v-for绑定的数组,index是索引,objectDetails是表单绑定的v-model的名称,然后用.把他们…

一文带你看透天气预报

天气预报是气象台(站)预先发出关于未来一定时期内的天气变化和趋势的报告。气象台运用现代科学技术(如卫星、雷达等)收集了全国甚至全世界的气象资料&#xff0c;根据天气演变规律&#xff0c;进行综合分析&#xff0c;科学判断&#xff0c;然后作出大范围的天气预报。气象站、…

m基于FPGA的分布式FIR滤波器verilog设计,对比普通结构以及DA结构

目录 1.算法描述 2.仿真效果预览 3.verilog核心程序 4.完整FPGA 1.算法描述 DA算法的主要特点是&#xff0c;巧妙地利用查找表将固定系数的MAC运算转化为查表操作&#xff0c;其运算速度不随系数和输入数据位数的增加而降低&#xff0c;而且相对直接实现乘法器而言&#xf…

软件测试面试技巧有哪些?这几点你得知道,不然后悔都来不及

新手测试技术不过硬&#xff0c;最害怕hr在面试时&#xff0c;问到技术方面的问题&#xff0c;那么在进行软件测试面试时&#xff0c;有哪些软件测试面试技巧可以帮助测试人&#xff0c;提高面试通过率呢&#xff1f; 接下来我就给大家总结了几个方面的面试技巧&#xff0c;希望…

【车载开发系列】UDS诊断---写入数据($0x2E)

【车载开发系列】UDS诊断—写入数据&#xff08;$0x2E&#xff09; UDS诊断---写入数据&#xff08;$0x2E&#xff09;【车载开发系列】UDS诊断---写入数据&#xff08;$0x2E&#xff09;一.概念定义二.应用场景三.报文格式1&#xff09;请求报文2&#xff09;肯定响应3&#x…

技术合集 | 【MySQL技术专题】「数据库锁技术」深入浅出透析MySQL数据库的锁基础概念和原理(上下全)

上篇 前提介绍 在计算机科学中&#xff0c;锁是在执行多线程时用于强行限制资源访问的同步机制&#xff0c;即用于在并发控制中保证对互斥要求的满足。 本文内容 本文主要介绍&#xff1a;行级锁、表级锁、页级锁的相关概念以及原理介绍 本文主要介绍&#xff1a;共享锁、排它…

论文速读系列二:YOLO3D、PIXOR、HDNET、Voxel-FPN、Fast Point RCNN

如有错误&#xff0c;恳请指出。 参考网上资料&#xff0c;对一些经典论文进行快速思路整理 文章目录1. YOLO3D2. PIXOR3. HDNET&#xff08;PIXOR&#xff09;4. Voxel-FPN5. Fast Point RCNN1. YOLO3D paper&#xff1a;《YOLO3D: End-to-end real-time 3D OrientedObject B…

领英怎么用多个账号一起开发客户?进阶知识

1.如何注册账号&#xff1f; LinkedIn经历调整 2021年12月14日起&#xff0c;领英(LinkedIn)正式被改版为领英职-场。在改版后的领英职-场上&#xff0c;我们既无法进行主动搜-索客户&#xff0c;添-加好友&#xff0c;也无法查看和发布动态内容&#xff0c;完完全全的变成了一…

ChatGPT 常见错误原因及解决方案:报错、回答不完整等

最近&#xff0c;由人工智能实验室 OpenAI 发布的对话式大型语言模型 ChatGPT 火得一塌糊涂。它可以与人类轻松地对话&#xff0c;无论是多么奇葩的问题 ChatGPT 都不在话下。在体验 ChatGPT 的同时我们也会遇到各种各样的问题&#xff0c;这里我总结了其对话过程中可能会发生的…

springboot中如何实现跨域请求

Springboot中如何处理跨域请求 一.什么是跨域? 我们知道Url的一般格式&#xff1a;协议 域名&#xff08;子域名 主域名&#xff09; 端口号 资源地址 比如&#xff1a; https://www.itquanmingxing.cn:8080/users 是由https www itquanmingxing.cn 8080 users组成…

普通程序员可以怎么做搞钱程序?

最近海洋问题实在是很严重&#xff0c;人类活动带来的垃圾污染等问题使海洋生物得到了很大的压力。 每年鱼类等海洋生物体内的塑料海量越来越多&#xff0c;不仅仅是由于日常人类日常使用的垃圾袋引起的。 还有很多方面的原因&#xff0c;最直接的因素就是去看海的游客遗留下…

云计算自学笔记(不定期更新)

管道命令使用 linux管道相关命令__小笼包_的博客-CSDN博客_linux管道命令 [cut ]&#xff1a;命令的功能是用于按列提取文件内容 按照字符提取命令&#xff1a;head -2 2.txt | cut -c 5 查看前两行&#xff0c;并按照字符提取第五个字符 -c 按照字符提取 截取出…