前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微信小程序+Java获取用户授权手机号码

微信小程序+Java获取用户授权手机号码

原创
作者头像
炒香菇的书呆子
修改2021-02-18 10:45:13
1.7K0
修改2021-02-18 10:45:13
举报
文章被收录于专栏:乌龟哥哥默认学习专栏

前言

小程序内可以直接通过授权获取用户微信号绑定的手机号码或用户添加的其他手机号码,这样可以使得小程序在进行账户的身份可控上又提高了一步,那么应该如何来获取手机号码呢?这篇文章就和大家一起来研究一下。

前提

值得注意的是,如果您要获取手机号码首先要满足如下要求:

注意:目前该接口针对非个人开发者,且完成了认证的小程序开放(不包含海外主体)。需谨慎使用,若用户举报较多或被发现在不必要场景下使用,微信有权永久回收该小程序的该接口权限。 – 微信开发平台

正文

获取授权信息

首先,我们需要使用button组件,其open-type的值要设置为getPhoneNumber,可参考button · 小程序,然后绑定bindgetphonenumber的回调函数,在用户点击按钮,弹起的授权框允许授权之后回调函数内会返回一个event的对象,在其对象的detail下分别存在两个值(可参考《获取手机号 · 小程序》):

参数

类型

说明

encryptedData

String

包括敏感数据在内的完整用户信息的加密数据

iv

String

加密算法的初始向量

接下来我们要模拟一次登录,调用wx.login,然后再授权成功的回调中获取授权code值,接着将上述的encryptedDataiv一并传送至服务端,接下来就开始进行服务端解密过程。

服务端解密

服务端接收到encryptedDataivcode值之后,进行微信授权登录一次,接口可参考:《code2Session · 小程序》,然后我们需要获取返回值中的session_key字段,即为会话秘钥。

在微信《开放数据校验与解密 · 小程序》中提供了多种编程语言的示例代码,但是就是没有Java的,不知道是不是微信团队从来不写Java

,于是我们就自己实现了一个WXBizDataCrypt,具体实现如下:

代码语言:txt
复制
public class WXBizDataCrypt {

    private String appid;

    private String sessionKey;

    public WXBizDataCrypt(String appid, String sessionKey)
    {
        this.appid = appid;
        this.sessionKey = sessionKey;
    }

    public JSONObject decryptData(String encryptedData, String iv) throws Exception{
        byte[] dataByte = Base64.decodeBase64(encryptedData);
        // 加密秘钥
        byte[] keyByte = Base64.decodeBase64(this.sessionKey);
        // 偏移量
        byte[] ivByte = Base64.decodeBase64(iv);
        try {
            // 如果密钥不足16位,那么就补足.  这个if 中的内容很重要
            int base = 16;
            if (keyByte.length % base != 0) {
                int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
                byte[] temp = new byte[groups * base];
                Arrays.fill(temp, (byte) 0);
                System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
                keyByte = temp;
            }
            // 初始化
            // 初始化
            Security.addProvider(new BouncyCastleProvider());
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
            parameters.init(new IvParameterSpec(ivByte));
            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
            byte[] resultByte = cipher.doFinal(dataByte);
            if (null != resultByte && resultByte.length > 0) {
                String result = new String(resultByte, "UTF-8");
                return JSONObject.parseObject(result);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

v_tips上述代码中并没有实现签名效验的相关业务,可自行实现/v_tips 首先我们需要创建WXBizDataCrypt的实体,传入小程序的appid与我们获取的session_key,然后再调用decryptData方法传入encryptedDataiv即可进行解密,如果返回的值为NULL或抛出异常则为解密失败,解密成功之后可以获取返回对象的countryCode以及purePhoneNumber组成完整的含区号的手机号码。

后记

在微信开放的相关开放接口中,对于用户的隐私数据这一块处理都是需要效验解密的,当然这一点也是为了数据安全,不过不得不吐槽有时候官方的文档真的是写的让人摸不着头脑,比如微信支付中的timestamptimeStamp :arrow:

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 前提
  • 正文
    • 获取授权信息
      • 服务端解密
      • 后记
      相关产品与服务
      云开发 CloudBase
      云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档