小程序如何獲取用戶綁定的手機號

小程序官方文檔中介紹:前端

獲取微信用戶綁定的手機號,需先調用wx.login接口。 由於須要用戶主動觸發才能發起獲取手機號接口,因此該功能不禁 API 來調用,需用 button 組件的點擊來觸發。java

注意:目前該接口針對非我的開發者,且完成了認證的小程序開放(不包含海外主體)。需謹慎使用,若用戶舉報較多或被髮如今沒必要要場景下使用,微信有權永久回收該小程序的該接口權限。具體可參考小程序APIweb

使用方法 須要將 button 組件 open-type 的值設置爲 getPhoneNumber,當用戶點擊並贊成以後,能夠經過 bindgetphonenumber 事件回調獲取到微信服務器返回的加密數據, 而後在第三方服務端結合 session_key 以及 app_id 進行解密獲取手機號。spring

<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">獲取手機號</button> 
複製代碼

在使用組件以前先調用loginapache

App({  
    onLaunch: function () {  
        wx.login({  
            success: function (res) {  
                if (res.code) {  
                    //發起網絡請求 
                    this.globalData.code = res.code;
                    console.log(res.code)  
                } else {  
                    console.log('獲取用戶登陸態失敗!' + res.errMsg)  
                }  
            }  
        });  
    },
    globalData: {}
})
複製代碼

getPhoneNumber中將返回用戶是否贊成受權的數據,小程序

const App = getApp();
Page({
    getPhoneNumber(e) {
        const { iv, encryptedData, errMsg } = e.detail;
        if (errMsg === 'getPhoneNumber:ok') {
            // 贊成受權
            wx.request({
                url: '/GetPhone',
                data: {
                    code: App.globalData.code,
                    iv,
                    encryptedData
                },
                success: (res) => {
                    console.log(res);
                }
            })
        }
    }
})
複製代碼

後端須要根據前端傳遞的code,iv, encryptedData,結合小程序的appID,secret,先獲取session_key,而後在進行電話號碼解析。爲了安全考慮,咱們的appID和secret都是存放在後端的,因此獲取session_key和電話解析都放後端進行了,前端只需調用接口便可。後端

獲取session_key的地址api

const APP_ID = '';
const SECRET = '';
const BASE_URL = 'https://api.weixin.qq.com';

const url = `${BASE_URL}/sns/jscode2session?appid=${APP_ID}&secret=${SECRET}&js_code=${res.code}&grant_type=authorization_code`;
複製代碼

電話號碼解析實例(java版)安全

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;
    }
複製代碼

注意:在回調中調用 wx.login 登陸,可能會刷新登陸態。此時服務器使用 code 換取的 sessionKey 不是加密時使用的 sessionKey,致使解密失敗。建議開發者提早進行 login;或者在回調中先使用 checkSession 進行登陸態檢查,避免 login 刷新登陸態。服務器

最後提醒你們,進入一個未知的小程序時,彈出用戶受權詢問框時,謹慎受權。以下圖

相關文章
相關標籤/搜索