微信开发获取手机号码

2016-01-12 12:44:59 u013142781 阅读数 12132

在本篇博客之前,博主已经写了4篇关于微信相关文章,其中三篇是本文基础:

1、微信开发之入门教程,该文章详细讲解了企业号体验号免费申请与一些必要的配置,以及如何调用微信接口。

2、微信开发之通过代理调试本地项目,该文章详细讲解了如何调试本地项目,使用工具的详细安装与配置。

3、微信开发之使用java获取签名signature(贴源码,附工程),该文详细讲些了如何获取签名,代码十分详细。

对于初学者,可能还不知道订阅号、服务号、和企业号的区别,博主之前也是一直没有弄清楚,因此查阅资料整理了一篇博客供大家阅读:微信服务号、订阅号和企业号的区别(运营和开发两个角度)。建议有时间得猿友还是阅读一下为好。

上面的文章内容虽然有点多而且繁琐,看完之后不敢说已经入门,但是初步了解,自己写实例是没有问题的。不积跬步无以至千里,希望猿友们耐心继续下去!!!!!!

上面的文章内容虽然有点多而且繁琐,看完之后不敢说已经入门,但是初步了解,自己写实例是没有问题的。不积跬步无以至千里,希望猿友们耐心继续下去!!!!!!

上面的文章内容虽然有点多而且繁琐,看完之后不敢说已经入门,但是初步了解,自己写实例是没有问题的。不积跬步无以至千里,希望猿友们耐心继续下去!!!!!!

期间可能会遇到一些坑,欢迎与博主评论交流

有了上面的基础,接下来博主将分享一个具体的微信开发实例,获取用户当前的地理位置。

一、结果演示

这里写图片描述 这里写图片描述
这里写图片描述 这里写图片描述

二、代码及代码讲解

本工程使用的环境是eclipse + maven + springmvc,下面附上关键代码,springmvc和web.xml相关配置和maven相关依赖就不一一列举,最后会附上工程供大家下载。

2.1、获取签名工具类(httpclient和sha1加密)

package com.luo.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import net.sf.json.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

public class HttpXmlClient {

    public static String post(String url, Map<String, String> params) {
        DefaultHttpClient httpclient = new DefaultHttpClient();
        String body = null;
        HttpPost post = postForm(url, params);
        body = invoke(httpclient, post);
        httpclient.getConnectionManager().shutdown();
        return body;
    }

    public static String get(String url) {
        DefaultHttpClient httpclient = new DefaultHttpClient();
        String body = null;
        HttpGet get = new HttpGet(url);
        body = invoke(httpclient, get);
        httpclient.getConnectionManager().shutdown();
        return body;
    }

    private static String invoke(DefaultHttpClient httpclient,
            HttpUriRequest httpost) {
        HttpResponse response = sendRequest(httpclient, httpost);
        String body = paseResponse(response);
        return body;
    }

    private static String paseResponse(HttpResponse response) {
        HttpEntity entity = response.getEntity();
        String charset = EntityUtils.getContentCharSet(entity);
        String body = null;
        try {
            body = EntityUtils.toString(entity);
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return body;
    }

    private static HttpResponse sendRequest(DefaultHttpClient httpclient,
            HttpUriRequest httpost) {
        HttpResponse response = null;
        try {
            response = httpclient.execute(httpost);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }

    private static HttpPost postForm(String url, Map<String, String> params) {

        HttpPost httpost = new HttpPost(url);
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();

        Set<String> keySet = params.keySet();
        for (String key : keySet) {
            nvps.add(new BasicNameValuePair(key, params.get(key)));
        }

        try {
            httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return httpost;
    }

    public static void main(String[] args) {

        //获取access_token
        Map<String, String> params = new HashMap<String, String>();
        params.put("corpid","wx5f24fa0db1819ea2");
        params.put("corpsecret","uQtWzF0bQtl2KRHX0amekjpq8L0aO96LSpSNfctOBLRbuYPO4DUBhMn0_v2jHS-9");
        String xml = HttpXmlClient.post("https://qyapi.weixin.qq.com/cgi-bin/gettoken",params);
        JSONObject jsonMap  = JSONObject.fromObject(xml);
        Map<String, String> map = new HashMap<String, String>();
        Iterator<String> it = jsonMap.keys();  
        while(it.hasNext()) {  
            String key = (String) it.next();  
            String u = jsonMap.get(key).toString();
            map.put(key, u);  
        }
        String access_token = map.get("access_token");
        System.out.println("access_token=" + access_token);

        //获取ticket
        params.put("access_token",access_token);
        xml = HttpXmlClient.post("https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket",params); 
        jsonMap  = JSONObject.fromObject(xml);
        map = new HashMap<String, String>();
        it = jsonMap.keys();  
        while(it.hasNext()) {  
            String key = (String) it.next();  
            String u = jsonMap.get(key).toString();
            map.put(key, u);  
        }
        String jsapi_ticket = map.get("ticket");
        System.out.println("jsapi_ticket=" + jsapi_ticket);

        //获取签名signature
        String noncestr = UUID.randomUUID().toString();
        String timestamp = Long.toString(System.currentTimeMillis() / 1000);
        String url="http://mp.weixin.qq.com";
        String str = "jsapi_ticket=" + jsapi_ticket +
                "&noncestr=" + noncestr +
                "&timestamp=" + timestamp +
                "&url=" + url;
        //sha1加密
        String signature = SHA1(str);
        System.out.println("noncestr=" + noncestr);
        System.out.println("timestamp=" + timestamp);
        System.out.println("signature=" + signature);
        //最终获得调用微信js接口验证需要的三个参数noncestr、timestamp、signature
    }

       /** 
     * @author:罗国辉 
     * @date: 2015年12月17日 上午9:24:43 
     * @description: SHA、SHA1加密
     * @parameter:   str:待加密字符串
     * @return:  加密串
    **/
    public static String SHA1(String str) {
        try {
            MessageDigest digest = java.security.MessageDigest
                    .getInstance("SHA-1"); //如果是SHA加密只需要将"SHA-1"改成"SHA"即可
            digest.update(str.getBytes());
            byte messageDigest[] = digest.digest();
            // Create Hex String
            StringBuffer hexStr = new StringBuffer();
            // 字节数组转换为 十六进制 数
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexStr.append(0);
                }
                hexStr.append(shaHex);
            }
            return hexStr.toString();

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }
}

2.2、controller代码(尽可能仔细阅读下面的每一行代码,特别是url部分)

package com.luo.controller;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.luo.util.HttpXmlClient;

@Controller  
public class UserController {  

    @RequestMapping("/")    
    public ModelAndView getIndex(HttpServletRequest request){  

        ModelAndView mav = new ModelAndView("index");  
        //获取access_token
        Map<String, String> params = new HashMap<String, String>();
        params.put("corpid","wx7099477f2de8aded");
        params.put("corpsecret","4clWzENvHVmpcyuA4toys0URkfYanIqWtxZ5plbisn6Cd5AVTF0thpaK6UAhjIvN");
        String xml = HttpXmlClient.post("https://qyapi.weixin.qq.com/cgi-bin/gettoken",params);
        JSONObject jsonMap  = JSONObject.fromObject(xml);
        Map<String, String> map = new HashMap<String, String>();
        Iterator<String> it = jsonMap.keys();  
        while(it.hasNext()) {  
            String key = (String) it.next();  
            String u = jsonMap.get(key).toString();
            map.put(key, u);  
        }
        String access_token = map.get("access_token");

        //获取ticket
        params.put("access_token",access_token);
        xml = HttpXmlClient.post("https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket",params); 
        jsonMap  = JSONObject.fromObject(xml);
        map = new HashMap<String, String>();
        it = jsonMap.keys();  
        while(it.hasNext()) {  
            String key = (String) it.next();  
            String u = jsonMap.get(key).toString();
            map.put(key, u);  
        }
        String jsapi_ticket = map.get("ticket");


        //获取签名signature
        String noncestr = UUID.randomUUID().toString();
        String timestamp = Long.toString(System.currentTimeMillis() / 1000);
        //获取请求url
        String path = request.getContextPath();
        //以为我配置的菜单是http://yo.bbdfun.com/first_maven_project/,最后是有"/"的,所以url也加上了"/"
        String url = request.getScheme() + "://" + request.getServerName() +  path + "/";  
        String str = "jsapi_ticket=" + jsapi_ticket +
                "&noncestr=" + noncestr +
                "&timestamp=" + timestamp +
                "&url=" + url;
        //sha1加密
        String signature = HttpXmlClient.SHA1(str);
        mav.addObject("signature", signature);   
        mav.addObject("timestamp", timestamp);   
        mav.addObject("noncestr", noncestr);   
        mav.addObject("appId", "wx7099477f2de8aded"); 
        System.out.println("jsapi_ticket=" + jsapi_ticket);
        System.out.println("noncestr=" + noncestr);
        System.out.println("timestamp=" + timestamp);
        System.out.println("url=" + url);
        System.out.println("str=" + str);
        System.out.println("signature=" + signature);
        return mav;    

    }    
}  

2.3、前端js代码(尽可能仔细阅读下面的每一行代码)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script>
    wx.config({
        debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: '${appId}', // 必填,企业号的唯一标识,此处填写企业号corpid
        timestamp: parseInt("${timestamp}",10), // 必填,生成签名的时间戳
        nonceStr: '${noncestr}', // 必填,生成签名的随机串
        signature: '${signature}',// 必填,签名,见附录1
        jsApiList: ['getLocation'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
    });
    wx.ready(function(){
    });

    wx.error(function(res){
    });
</script>
</head>
<body>
<button id="getBBS" style="width:1000px;height:600px;font-size:150px;" onclick="submitOrderInfoClick();">获取地理位置</button>
</body>
<script type="text/javascript">
function submitOrderInfoClick(){
  wx.getLocation({
        success: function (res) {
            alert("小宝鸽获取地理位置成功,经纬度为:(" + res.latitude + "," + res.longitude + ")" );
        },
        fail: function(error) {
            AlertUtil.error("获取地理位置失败,请确保开启GPS且允许微信获取您的地理位置!");
        }
    });
}
</script>
</html>

三、源码下载

http://download.csdn.net/detail/u013142781/9400470

加上这篇文章,博主微信相关文章就有5篇,将会点亮博主微信开发博客专栏(左侧可看到),欢迎订阅。

欢迎相互关注交流,博主会不断将工作上遇到的技术点写成博客分享给大家。

2019-01-10 16:37:36 weixin_42799222 阅读数 5291

一、前沿研究

  1. 微信公众号开发文档,浏览后没有任何关于获取微信运动数据的接口

    https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432

  2. 微信小程序开发文档,浏览后,发现获取微信运动数据的接口

         https://developers.weixin.qq.com/miniprogram/dev/api/wx.getWeRunData.html

     3. 研究了相关运动统计小程序和微信公众号排行。 

         列举一下:

         小程序:步数宝、我要运动、SPC运动宝等。

         公众号:微信运动、乐心运动、华为运动健康等。

二、方案研究

    ​根据多方验证,微信公众号直接获取用户运动数据是不可能的,只能通过其他的工具进行数据存储,然后在微信公众号中展示运动数据信息。

    ​方案一:开发APP,通过App获取手机硬件授权,读取手机运动量数据,然后上传到后台服务器进行数据储蓄。

    ​   优点:数据来源稳定,数据内容信息不受其他平台运行限制,功能可自定义进行扩展。

    ​   缺点:功能不是很大的应用用户会认为占用内存,开发时间长,费用高,还需要开发安卓和苹果两个系统。应用必须保证在后台持续运行,必须获取到手机授权才可读取数据。

    ​方案二:毕竟重点是微信公众号,可以依托于微信平台,开发一个可以获取微信运动数据的小程序,还可以在微信小程序中开发其他相关的功能,然后和微信公众号进行菜单绑定,然后台微信公众号中做一些微信排行的奖励活动。让大家积极地使用,来获取最真实最实时的运动数据。

    ​    ​优点:可快速开发,开发成本低,缩短上线时间。同样是微信公众号,既提高了用户活跃程度,也达到了原有的目的。用户不必再安装应用,再重复获取用户运动授权信息,占用手机内存等。

三、倾听意见和建议

    ​请相关人员,自己也可以研究一下,或者多多浏览同行的功能实现方案。如果技术上支持,那我们一定可以的。有更好的方法或者方案,可以直接联系我,或者在评论区写下您的见解。

    ​明人不说暗话,我们一直在努力。

 

 

 

2019-09-04 10:40:30 u010757785 阅读数 17021

都知道微信公众号获取不到手机号,但是小程序可以。

今天大早晨老大死磕非要我公众号授权获取到手机号。没办法我还是有其他方法解决。

第一步:服务号添加一个小程序,网上有很多小程序授权的代码。确定小程序可以授权成功并且能获取到手机号

第二部:服务号网页授权成功获取到open_id记录到用户表里面

第三部:网页授权成功之后调用小程序,授权获取手机号

第四部:小程序获取到手机号成功之后调回到网页

这里就成功使用微信公众号获取到用户手机号

h5跳转到小程序

wx.miniProgram.navigateTo({url: '/pages/index/kjcgcon/kjcgcon'})

如果要传值可以直接在url后面加参数
wx.miniProgram.navigateTo({url: '/pages/scenic/scenic_detail/kjcg?uid='+uid})

注意要添加js
<script src='https://res.wx.qq.com/open/js/jweixin-1.3.0.js'></script>

小程序跳转到的H5页面,

<web-view src="https://zgl.seamo.cn/zglh5/kjzjlist1.html"></web-view>

参考资料

https://developers.weixin.qq.com/community/develop/doc/00006243d68f38dfea5639dcb56000

 

2020-03-01 09:41:08 foreverinter1908 阅读数 1600

关键坑点:

1. 不了解调用流程:流程->前台JS获取code-->post至后台api-->先获取session_key【调用微信api,返回json】-->解密手机号方法

2. 解密方法缺少包,需要不断添加包

3.解密方法没有问题,仍然无法获取,网上找资料清理缓存。问题解决。

 

第一步:wxml增加按钮

<button class='pop_btn' plain="true" open-type='getPhoneNumber' bindgetphonenumber="getPhoneNumber">获取用户手机号</button>

第二步:js文件调用后台

getPhoneNumber(e) {

console.log(e.detail.errMsg)

console.log(e.detail.iv)

var encryptedData = e.detail.encryptedData

console.log(encryptedData)

var code=""

var that = this;

console.log(e.detail.errMsg == "getPhoneNumber:ok");

if (e.detail.errMsg == "getPhoneNumber:ok") {

wx.login({

success: function (res) {

code = res.code

console.log("code_s")//这就是code

console.log( res.code)//这就是code

console.log("code_e")//这就是code

wx.request({

url: 'https://XXXXXXX',

method: "post",

header: {

'content-type': 'application/x-www-form-urlencoded;charset=utf-8'

},

data: {

encryptedData: e.detail.encryptedData,

iv: e.detail.iv,

code: res.code

},

 

success: function (res) {

console.log(res);

}

})

}

})

}

},

第三步:后台代码,分2步;第一步获取seesion_key;第二步解密手机号

Api服务方法

    @RequestMapping("/decodephone")
    public void  decodePhone(HttpServletRequest request, HttpServletResponse response,String encryptedData,String iv,String code){
        String mbody=StringUtils.ReadAsChars(request);
        System.out.println(mbody);
        String  msession_key= HttpUtil.doGet("https://api.weixin.qq.com/sns/jscode2session","appid=您的API的ID&secret=您的秘钥&js_code=前端传过来的CODE&grant_type=authorization_code");

        WeChatAppSessionModel mdl1=JSONObject.parseObject(msession_key, WeChatAppSessionModel.class);
        if(mdl1 !=null && mdl1.getSession_key()!=null)
        {
        try {
                mbody=AES.wxDecrypt(encryptedData, mdl1.getSession_key(), iv);
                response.getWriter().write("123");
            } catch (Exception e) {
                e.printStackTrace();
            }
        
        }
        System.out.println("调用结束");
    }

doGet 公共方法

 public static String doGet(String url,String parameter)
    {
        String uriAPI =url+"?"+parameter ; //"http://XXXXX?str=I+am+get+String";
        String result= "";
        HttpClient client = createSSLClientDefault();
        HttpGet httpRequst = new HttpGet(uriAPI);
        try {

            HttpResponse httpResponse = client.execute(httpRequst);//其中HttpGet是HttpUriRequst的子类
            if(httpResponse.getStatusLine().getStatusCode() == 200)
            {
                HttpEntity httpEntity = httpResponse.getEntity();
                result = EntityUtils.toString(httpEntity);//取出应答字符串
                // 一般来说都要删除多余的字符
                result.replaceAll("\r", "");//去掉返回结果中的"\r"字符,否则会在结果字符串后面显示一个小方格
            }
            else
                httpRequst.abort();
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            result = e.getMessage().toString();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            result = e.getMessage().toString();
        }
        return result;
    }

解密方法


import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.Security;
 
public class AES {
  // 算法名
  public static final String KEY_NAME = "AES";
  // 加解密算法/模式/填充方式
  // ECB模式只用密钥即可对数据进行加密解密,CBC模式需要添加一个iv
  public static final String CIPHER_ALGORITHM = "AES/CBC/PKCS7Padding";
 
  /**
   * 微信 数据解密<br/>
   * 对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充<br/>
   * 对称解密的目标密文:encrypted=Base64_Decode(encryptData)<br/>
   * 对称解密秘钥:key = Base64_Decode(session_key),aeskey是16字节<br/>
   * 对称解密算法初始向量:iv = Base64_Decode(iv),同样是16字节<br/>
   *
   * @param encrypted 目标密文
   * @param session_key 会话ID
   * @param iv 加密算法的初始向量
   */
  public static String wxDecrypt(String encrypted, String session_key, String iv) {
    String json = null;
    byte[] encrypted64 = Base64.decodeBase64(encrypted);
    byte[] key64 = Base64.decodeBase64(session_key);
    byte[] iv64 = Base64.decodeBase64(iv);
    byte[] data;
    try {
      init();
      json = new String(decrypt(encrypted64, key64, generateIV(iv64)));
    } catch (Exception e) {
      e.printStackTrace();
    }
    return json;
  }
 
  /**
   * 初始化密钥
   */
  public static void init() throws Exception {
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    KeyGenerator.getInstance(KEY_NAME).init(128);
  }
 
  /**
   * 生成iv
   */
  public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
    // iv 为一个 16 字节的数组,这里采用和 iOS 端一样的构造方法,数据全为0
    // Arrays.fill(iv, (byte) 0x00);
    AlgorithmParameters params = AlgorithmParameters.getInstance(KEY_NAME);
    params.init(new IvParameterSpec(iv));
    return params;
  }
 
  /**
   * 生成解密
   */
  public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes, AlgorithmParameters iv)
      throws Exception {
    Key key = new SecretKeySpec(keyBytes, KEY_NAME);
    Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
    // 设置为解密模式
    cipher.init(Cipher.DECRYPT_MODE, key, iv);
    return cipher.doFinal(encryptedData);
  }
 
}

2018-05-28 17:11:34 weixin_38984353 阅读数 11656

小程序中有很多地方都会用到注册用户信息的地方,用户需要填写手机号等,

      有了这个组件可以快速获取微信绑定手机号码,无须用户填写。


1.getPhoneNumber这个组件通过button来实现(别的标签无效)。将button中的open-type=“getPhoneNumber”,并且绑定bindgetphonenumber事件获取回调。

<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"> 获取手机号码</button>

这个组件之前必须先调用login接口,如果没有调用login点击button时会提示先调用login。

[html] view plain copy
  1. wx.login({
    success: function (res) {
    // console.log(res);
    if (res.code) {
    //发起网络请求
    wx.request({
    url: ''
    data: {
    code: res.code
    },
    success: function (response) {
    console.log(response);
    var openId = response.data.openid;
    var session_key = response.data.session_key;
    var app = getApp();
    app.globalData.openid = openId;
    app.globalData.session_key = session_key;
    typeof cb == "function" && cb()

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



3.通过bindgetphonenumber绑定的事件来获取回调。回调的参数有三个,

errMsg:用户点击取消或授权的信息回调。

iv:加密算法的初始向量(如果用户没有同意授权则为undefined)。

encryptedData: 用户信息的加密数据(如果用户没有同意授权同样返回undefined)


[html] view plain copy
  1. getPhoneNumber: function(e) {   
  2.     
    var that=this;
    var session_key=app.globalData.session_key;

    if (e.detail.errMsg == 'getPhoneNumber:fail user deny') {
    wx.showModal({
    title: '提示',
    showCancel: false,
    content: '未授权',
    success: function (res) { }
    })
    } else {

    wx.checkSession({
    success: function () {
    console.log(1);
    wx.request({
    url: 'https://m.xianmaogame.com/sd_idiom/xcx/getPhoneNumber/demo.php',
    data: {
    encryptedData:e.detail.encryptedData,
    iv:e.detail.iv,
    sessionKey:session_key
    },
    method: 'GET',
    success: function (res) {
    console.log('获取手机号码成功');
    console.log(res);
    }
    })
    },
    fail: function () {
    console.log(2);
    wx.login({
    success: function (res) {
    if (res.code) {
    //发起网络请求
    wx.request({
    url: ''
    data: {
    code: res.code
    },
    success: function (response) {
    var openId = response.data.openid;
    var session_key = response.data.session_key
    wx.request({
    url: '',
    data: {
    encryptedData: e.detail.encryptedData,
    iv: e.detail.iv,
    sessionKey: session_key
    },
    method: 'GET',
    success: function (res) {
    console.log('获取手机号码成功');
    console.log(res);
    }
    })
    }
    })
    } else {
    console.log('获取用户登录态失败!' + res.errMsg)
    }
    }
    });
    }
    })
    }

  3.   }  
4.最后我们需要根据自己的业务逻辑来进行处理,如果用户不同意授权的话可能我们会有一个让他手动输入的界面,如果不是强制获取手机号的话可以直接跳转页面进行下一步。(用户不同意授权errMsg返回‘getPhoneNumber:fail user deny’)

5.用户同意授权,我们可以根据login时获取到的code来通过后台以及微信处理拿到session_key,最后通过app_id,session_key,iv,encryptedData(用户同意授权errMsg返回‘getPhoneNumber:ok’)

6.解密的方法可以去微信官方开发文档查看,有很详细说明。