微信小程序如何获取用户手机号

yizhihongxing

微信小程序可以使用手机号作为用户的唯一标识,可以通过微信提供的API获取用户的手机号,具体操作步骤如下:

1. 开启微信用户手机号授权

在小程序的app.json文件中,设置如下选项,表示开启用户手机号授权功能:

{
  "permission": {
    "scope.userLocation": {
      "desc": "你的位置信息将用于小程序定位"
    },
    "scope.userInfo": {
      "desc": "你的基本信息将用于小程序个性化体验"
    },
    "scope.userPhone": {
      "desc": "你的手机号将用于小程序验证身份"
    }
  }
}

2. 获取用户手机号

小程序开发者可以通过wx.login接口获取到用户的code,然后将code发送到开发者后台,后台通过code获取session_key和openid,在获取到session_key后,根据微信提供的文档,通过encryptedDataiv可以解密出用户的手机号。

具体的代码示例如下:

wx.login({
  success: function (res) {
    if (res.code) {
      // 发送res.code到后台换取openId, session_key, unionId
      wx.request({
        url: 'https://api.weixin.qq.com/sns/jscode2session',
        data: {
          appid: 'your appid',
          secret: 'your app secret',
          js_code: res.code,
          grant_type: 'authorization_code'
        },
        success: function (response) {
          if (response.statusCode === 200) {
            const session_key = response.data.session_key
            const encryptedData = e.detail.encryptedData
            const iv = e.detail.iv
            wx.request({
              url: '/decryptPhoneNumber',
              method: 'POST',
              data: {
                sessionKey: session_key,
                encryptedData: encryptedData,
                iv: iv
              },
              success: function (response) {
                const phoneNumber = JSON.parse(response.data)
                console.log(phoneNumber)
              }
            })
          } else {
            console.log(response.errMsg)
          }
        }
      })
    } else {
      console.log('登录失败!' + res.errMsg)
    }
  }
})

3. 示例说明

示例1:使用微信手机号 API 加密数据

可以使用微信提供的 wx.login() 接口获取到用户的code,然后将code发送到开发者后台,通过开发者后台的接口获得unionId和session_key,最后引用wx.createCipher模块完成加密操作。具体代码示例如下:

const crypto = require('crypto')

function decodePhone(data, sessionKey) {
  // base64 decode
  const encryptedData = new Buffer(data, 'base64')
  const key = new Buffer(sessionKey, 'base64')
  const iv = key
  try {
    // 解密数据
    const decipher = crypto.createDecipheriv('aes-128-cbc', key, iv)
    decipher.setAutoPadding(true)
    let decoded = decipher.update(encryptedData, 'binary', 'utf8')
    decoded += decipher.final('utf8');

    decoded = JSON.parse(decoded)
  } catch (err) {
    throw new Error('Illegal Buffer')
  }

  if (decoded.watermark.appid !== appid) {
    throw new Error('Illegal Buffer')
  }

  return decoded
}

Page({
  data: {},
  getPhoneNumber: function(e) {
    const detail = e.detail
    wx.login({
      success: (res) => {
        if (res.code) {
          // 发送 res.code 到后台换取 unionId, session_key 
          wx.request({
            url: '/decodePhoneNumber',
            header: {
              'content-type': 'application/x-www-form-urlencoded'
            },
            method: 'POST',
            data: {
              appid: appid,
              code: res.code,
              encryptedData: detail.encryptedData,
              iv: detail.iv
            },
            success: (res) => {
              const data = res.data
              if (data.errcode === 0) {
                const phoneNumber = decodePhone(data, data.session_key)
                console.log('用户手机号为', phoneNumber)
              }
            },
            fail: (res) => {
            }
          })
        }
      },
      fail: (res) => {
      }
    })
  }
})

示例2:手动解密数据

也可以使用手动解密的方式获取用户手机号,具体的代码示例如下:

function unescapeUnicode(data) {
  return data.replace(/\\u/g, '%u')
  .replace(/[^\x00-\x7F]/g, function(u) {return decodeURIComponent(unescape(unicodeEscape(u)))})
}

function unicodeEscape(str) {
  let res = '';
  for (let i = 0; i < str.length; i++) {
    res += '\\u' + str.charCodeAt(i).toString(16).padStart(4, '0');
  }
  return res;
} 

function decodePhone(data, sessionKey, iv) {
  // base64 decode
  const encryptedData = new Buffer(data, 'base64')
  const key = new Buffer(sessionKey, 'base64')
  iv = new Buffer(iv, 'base64')

  try {
    // 解密数据
    const decipher = crypto.createDecipheriv('aes-128-cbc', key, iv)
    decipher.setAutoPadding(true)
    let decoded = decipher.update(encryptedData, 'binary', 'utf8')
    decoded += decipher.final('utf8')

    decoded = JSON.parse(unescapeUnicode(decoded))
  } catch (err) {
    console.error('解密出现异常', err)
    throw err
  }

  if (decoded.watermark.appid !== getApp().globalData.appId) {
    console.error('appId不一致', decoded)
    throw new Error('appId不一致')
  }

  return decoded
}

Page({
  data: {},
  getPhoneNumber: function(e) {
    const detail = e.detail
    wx.login({
      success: (res) => {
        if (res.code) {
          wx.request({
            url: '/api/user/phone-number',
            header: {
              'content-type': 'application/x-www-form-urlencoded'
            },
            method: 'POST',
            data: {
              code: res.code,
              encryptedData: detail.encryptedData,
              iv: detail.iv
            },
            success: (res) => {
              const data = res.data
              if (data.success) {
                const phoneNumber = decodePhone(detail.encryptedData, data.session_key, detail.iv)
                console.log('用户手机号为', phoneNumber)
                // 修改页面上的手机号展示信息
              } else {
                console.error(data.msg)
              }
            },
            fail: (res) => {
            }
          })
        }
      },
      fail: (res) => {
      }
    })
  }
})

在以上的代码中,我们通过wx.login()获取到用户的code,再将其发给后台以获得session_key,最后利用得到的手机号的密文、session_key以及iv,使用crypto模块的decipher()方法解密数据。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:微信小程序如何获取用户手机号 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • PHP实现的AES双向加密解密功能示例【128位】

    下面是“PHP实现的AES双向加密解密功能示例【128位】”的完整攻略: 1. 如何实现AES加密解密功能? 要使用PHP实现AES加密解密功能,我们需要使用PHP的mcrypt扩展。具体步骤如下: 安装mcrypt扩展:在Linux环境下,可以使用以下命令行安装:sudo apt-get install php5-mcrypt;在Windows环境下,可以…

    PHP 2023年5月26日
    00
  • PHP 数字左侧自动补0

    下面是关于“PHP 数字左侧自动补0”的完整攻略: 1. 使用 str_pad 函数进行补零操作 PHP中可以使用 str_pad 函数在左侧添加指定数量的字符进行补零操作。 语法: str_pad($str, $length, $padString, $padType); 参数说明: $str:需要补零的数字字符串; $length:指定最终的字符串长度,…

    PHP 2023年5月26日
    00
  • PHP实现文件上传后台处理脚本

    首先我们先来介绍一下PHP实现文件上传后台处理脚本的基本流程: 通过HTML表单上传文件到后台PHP处理文件 PHP对上传的文件进行一些安全性验证 PHP将上传的文件移动到指定目录 PHP返回上传文件的相关信息,比如文件名、文件类型、文件大小等 下面我们就来详细讲解一下该流程的具体实现过程。 1. 前端HTML表单设计 在HTML代码中,需要设置form表单…

    PHP 2023年5月26日
    00
  • PHP7数组的底层实现示例

    下面是 PHP7 数组的底层实现示例的详细攻略。 什么是 PHP7 数组? PHP7 数组指的是 PHP 语言中的数组类型,它是一种可以存储多个值的数据类型。PHP 数组的特点是可以动态地添加、删除和修改元素,而且支持多种不同类型的元素。在 PHP7 中,数组的底层实现有了很大改进,提高了数组的性能和效率。 PHP7 数组的底层实现 PHP7 数组的底层实现…

    PHP 2023年5月27日
    00
  • PHP实现15位身份证号转18位的方法分析

    PHP实现15位身份证号转18位的方法分析 在国家实行全民身份证制度之前,早期颁发的身份证都只有15位号码,这些15位身份证号的最后一位校验码是随机生成的。在现在的全民身份证制度下,身份证号码都是18位,其中最后一位是通过前17位号码计算得出的校验码。对于一些老旧的记录系统或早期数据采集结果,需要将15位身份证号转换成18位,这就需要用到身份证号码的规则。 …

    PHP 2023年5月26日
    00
  • php array_map使用自定义的函数处理数组中的每个值

    下面是关于 “php array_map使用自定义的函数处理数组中的每个值” 的完整攻略。 什么是 array_map 函数? array_map 函数是 PHP 标准库中的函数,它将一个数组的所有元素通过某个回调函数映射到另一个数组中,并返回新的数组。通俗的来说,就是通过一个函数对一个数组中的每个元素做处理,得到一个经过处理后的新数组。 array_map…

    PHP 2023年5月26日
    00
  • PHP 文件类型判断代码

    那么我将为您详细讲解如何判断 PHP 文件类型的方法。 PHP 文件类型判断 在 PHP 中,有多种方法可以用来判断一个文件的类型,下面介绍两种常见的方法。 方法一:使用文件扩展名 文件扩展名是文件名的末尾中最后一个点(.)后面的字母。可以使用 pathinfo() 函数获取到文件名的扩展名。 $file = ‘path/to/file.php’; $ext…

    PHP 2023年5月26日
    00
  • PHPCMS v9 安全设置、防范教程

    PHPCMS v9 安全设置、防范教程 在使用PHPCMS v9建站的时候,要注意安全问题。本文将介绍一些常见的安全设置和防范措施,以确保您的网站不会受到攻击。 1. 使用强密码 在PHPCMS v9后台登录时,建议使用复杂的密码,包含大小写字母、数字和符号。这样可以有效地防止被猜测或撞库攻击。 示例说明: 以下是一个例子,展示了一个很容易被攻击的密码: A…

    PHP 2023年5月24日
    00
合作推广
合作推广
分享本页
返回顶部