微信小程序手机号解析获取

 

 

我使用了两种方式,分享出来,新人练手,不喜勿喷。一种是通过js方式直接解析,一种是传输给后台通过java进行解析。关键参数三个encryptedData,iv,session-key。

1.通过wx.login,获取res.code,将其发送给腾讯服务器,获取session_key

//app.js里面
App({
  onLaunch: function () {
    // 展示本地存储能力
    var logs = wx.getStorageSync('logs') || []
    logs.unshift(Date.now())
    wx.setStorageSync('logs', logs)
    // 登录
    wx.login({
      success: res => {
       // 发送 res.code 到后台换取 openId, sessionKey, unionId
        if (res.code) {
          //发起网络请求
          wx.request({

            url: 'https://api.weixin.qq.com/sns/jscode2session',
             data: {
//这里提一下我中的坑,appid和appsecret可以通过测试号来获取,自己的appid和appsecret放在这里好像也获取不了,测试号获取怎么弄,在微信开发者工具上面有个测试号,点击进去可以进入小程序的开发者文档,里面有个申请测试号,。只需访问 申请地址 ,点击蓝色的申请地址,里面链接中就有appid和secret。当然你能用自己正式的appid和secret成功获取到了session-key,就忽略这句话吧
               appid: 'wxb805796eb9*****',//小程序的ID
               secret: 'eaed34b32421*******',//小程序的密钥
               js_code: res.code,
               grant_type: 'authorization_code'
            },
            method: 'GET',
            header: {
              'content-type': 'application/json' // 默认值
            },
            success: function (response) {
              console.log(response);
              var openId = response.data.openid;
              var session_key = response.data.session_key;  //这里就获取了session-key
             
              console.log(session_key + "//?????" + openId);
              var app = getApp();
              app.globalData.openid = openId;
              app.globalData.session_key = session_key;
              typeof cb == "function" && cb()

            },fail: function (res) {
              console.log('获取openId、sessionKey失败!' + res.errMsg)
            }
          })
        } else {
          console.log('获取用户登录态失败!' + res.errMsg)
        }
      }
    })

考虑到某些小伙伴的appid和secret没有或者无法有效获取到session-key,自己有没有获取到session-key控制台打印一下就知道了,如果appid和secret无法获取到session-key的话,可以使用测试号提供的appid和secret来尝试,我反正使用测试号获取到的,这里提供通过测试号获取appid和secret的过程。

微信小程序手机号解析获取_第1张图片

微信小程序手机号解析获取_第2张图片

微信小程序手机号解析获取_第3张图片

 

2.获取session_key后,现在来获取encryptedData,iv。

//创建一个getphone.wxml文件
  
    
      
const app = getApp()
var WXBizDataCrypt = require('../../utils/RdWXBizDataCrypt.js');
Page({

  canIUse: wx.canIUse('button.open-type.getUserInfo'),

  /**
   * 页面的初始数据
   */
  data: {

    AppId: ''
  },

  blindgetPhone: function(e) {
   
    // 获取session-key
    var session_key = app.globalData.session_key;
    var openid = app.globalData.openid;
    var AppId = "wxb805796eb******";
  // 获取encryptedData、iv这两个参数
    var encryptedData = e.detail.encryptedData;
    var iv = e.detail.iv;
    console.log(session_key + "///")

    if (e.detail.errMsg == 'getPhoneNumber:fail user deny') {
      wx.showModal({
        title: '提示',
        showCancel: false,
        content: '手机号码未授权,请授权后再使用',
        success: function(res) {}
      })
    } else {
      //检查sessionkey状态,如果用户session-key无效则重新登录获取session-key,
      // 如果有效,则通过传入三个参数encryptedData,iv,session-key进行手机号解析
      wx.checkSession({
        success: function() {
          console.log("session_key 未过期,并且在本生命周期一直有效");
          console.log("-----" + AppId + "------" + session_key + "---" + encryptedData + "" + iv);
          var pc = new WXBizDataCrypt(AppId, session_key)
          var data = pc.decryptData(encryptedData, iv)
          app.globalData.phoneNumber = data.phoneNumber
          console.log(app.globalData.phoneNumber + "------------");
          wx.setStorageSync('phoneNumber', data.phoneNumber);
}
})
}
}
       

3.复制到这里了,会发现1个陌生的代码, WXBizDataCrypt,好的,接下来创建utils目录,在utils里面创建一个WXBizDataCrypt.js以供上面代码使用,在WXBizDataCrypt.js里面又引用了别的组件,我也提供一个该文件夹下载地址给你(https://github.com/gwjjeff/cryptojs/archive/master.zip),将该文件夹也放在utils目录里面,也可以参考别人的文章了解详情https://www.cnblogs.com/cai-rd/p/6816849.html

创建WXBizDataCrypt.js,别问我,整个代码复制过去就行,我也没理清楚

/**
 * Created by rd on 2017/5/4.
 */
// 引入CryptoJS
var Crypto = require('cryptojs-master/cryptojs.js').Crypto;
var app = getApp();

function RdWXBizDataCrypt(appId, sessionKey) {
  this.appId = appId
  this.sessionKey = sessionKey
}

RdWXBizDataCrypt.prototype.decryptData = function (encryptedData, iv) {
  // base64 decode :使用 CryptoJS 中 Crypto.util.base64ToBytes()进行 base64解码
  var encryptedData = Crypto.util.base64ToBytes(encryptedData)
  var key = Crypto.util.base64ToBytes(this.sessionKey);
  var iv = Crypto.util.base64ToBytes(iv);

  // 对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充
  var mode = new Crypto.mode.CBC(Crypto.pad.pkcs7);

  try {
    // 解密
    var bytes = Crypto.AES.decrypt(encryptedData, key, {
      asBpytes: true,
      iv: iv,
      mode: mode
    });

    var decryptResult = JSON.parse(bytes);

  } catch (err) {
    console.log(err)
  }

  if (decryptResult.watermark.appid !== this.appId) {
    console.log(err)
  }

  return decryptResult
}

module.exports = RdWXBizDataCrypt

接下来提供第二种方式,通过java代码来实现手机号解析。

const app = getApp()
Page({

  canIUse: wx.canIUse('button.open-type.getUserInfo'),

  /**
   * 页面的初始数据
   */
  data: {

     },
 

 getPhoneNumber: function(e) {

    // 获取session-key
    var that = this;
    var session_key = app.globalData.session_key;
    console.log(session_key + "///")
       console.log(e.detail.errMsg)
    console.log(e.detail.iv)
    console.log(e.detail.encryptedData)

    if (e.detail.errMsg == 'getPhoneNumber:fail user deny') {
      wx.showModal({
        title: '提示',
        showCancel: false,
        content: '手机号码未授权,请授权后再使用',
        success: function(res) {}
      })
    } else {
      //检查sessionkey状态,如果用户session-key无效则重新登录获取session-key,
      // 如果有效,则将encryptedData,iv,session-key发送给开发中服务器进行数据解析

      wx.checkSession({
        success: function() {
          console.log("session_key 未过期,并且在本生命周期一直有效");
          wx.request({
            url: 'http://localhost:8080/getPhoneNumber',
            data: {
              encryptedData: e.detail.encryptedData,
              iv: e.detail.iv,
              sessionKey: session_key
            },
            method: 'POST',
            header: {
              'content-type': 'application/x-www-form-urlencoded'
            },
            success: function(res) {

              console.log('解析手机号码成功');
              console.log(res);
              app.globalData.phoneNumber = res.data.phoneNumber

              console.log(app.globalData.phoneNumber + "------------");
            },
            fail: function(res) {
              console.log("解析手机号失败")
            }
          })
        },
        fail: function() {
          console.log("session_key 已经失效,需要重新执行登录流程");
          wx.login({
            success: function(res) {
              if (res.code) {
                //发起网络请求
                wx.request({
                  url: 'https://api.weixin.qq.com/sns/jscode2session',
                  data: {
                    appid: 'wxb805796*******', //小程序的ID
                    secret: 'eaed34b32421c150c***********', //小程序的密钥
                    js_code: res.code,
                    grant_type: 'authorization_code'
                  },
                  method: 'GET',
                  header: {
                    'content-type': 'application/json' // 默认值
                  },
                  success: function(response) {
                    var openId = response.data.openid;
                    var session_key = response.data.session_key
                    wx.request({
                      url: 'http://localhost:8080/getPhoneNumber',
                      data: {
                        encryptedData: e.detail.encryptedData,
                        iv: e.detail.iv,
                        sessionKey: session_key
                      },
                      method: 'POST',
                      header: {
                        'content-type': 'application/x-www-form-urlencoded'
                      },
                      success: function(res) {
                        console.log('获取手机号码成功');
                        console.log(res);
                        app.globalData.phoneNumber = res.data.phoneNumber

                      }
                    })
                  }
                })
              } else {
                console.log('获取用户登录态失败!' + res.errMsg)
              }
            }
          });
        }
      })
    }

java后台代码,需要的jar包我就不说了,也说不清楚,自己靠工具提示下载吧。

import org.apache.shiro.codec.Base64;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;

@Controller

public class GetPhone {
	/*用户手机号解析*/
	@RequestMapping("/getPhoneNumber")
	@ResponseBody
	public String getPhoneNumber(String encryptedData, String iv, String sessionKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {

		System.out.println(encryptedData + "-------" + iv + "-------" + sessionKey);

		byte[] encData = Base64.decode(encryptedData);
		byte[] keyByte = Base64.decode(iv);
		byte[] key = Base64.decode(sessionKey);

		AlgorithmParameterSpec ivSpec = new IvParameterSpec(keyByte);
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
		SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
		cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);// 初始化
		byte[] resultByte = cipher.doFinal(encData);
		if (null != resultByte && resultByte.length > 0) {
			String result = new String(resultByte, "UTF-8");
			System.out.println(result);
			return result;
		}
		return null;
	}

完结了。

你可能感兴趣的:(微信小程序)