2023年7月2日发(作者:)
微信⼩程序获取⼿机号JavaScript解密⽰例代码详解当我们在开发微信⼩程序中,有⼀个常⽤的功能,就是获取⽤户的⼿机号,然后⼀键登⼊⼩程序,那么⼿机号如何获取呢?请认真看完本⽂,保证可以获取到⽤户的⼿机号。刚开始开发微信⼩程序的时候,想着实现⼿机验证码登⼊,后来查阅资料得知,发给⽤户的短信是要⾃⼰付费的。后来想想,微信获取⽤户的⼿机号⼀样可以保证⼿机号码的真实性,因为⼿机号既然可以绑定微信,那么肯定是被严格核验过的,然后就开始了获取⼿机号之旅,⽹上教程有很多,但不知什么原因,都是会少⼀些内容,有的只有前端代码,没有后端;有的后端代码是PHP,不是我们想要的 Java 或者JavaScript。我抱着开源的思想,给⼤家分享我获取⼿机号的办法,希望能帮到⼤家。⾸先我们可以去看⼀看官⽅⽂档,获取⼿机号⼤致分为以下四步:第1步:使⽤接⼝获取code(临时数据)第2步:使⽤第⼀步的code,获取session_key和openid(确认⽤户唯⼀的数据)第3步:使⽤getPhoneNumber接⼝,获取iv和encryptedData(获取加密的数据)第4步:解密返回数据,获取⼿机号码(解密后的数据)下⾯详细讲解:第⼀步:使⽤接⼝获取code(临时数据)官⽅⽂档是这么写的:获取微信⽤户绑定的⼿机号,需先调⽤接⼝。因为需要⽤户主动触发才能发起获取⼿机号接⼝,所以该功能不由 API 来调⽤,需⽤ button 组件的点击来触发。注意:⽬前该接⼝针对⾮个⼈开发者,且完成了认证的⼩程序开放(不包含海外主体)。需谨慎使⽤,若⽤户举报较多或被发现在不必要场景下使⽤,微信有权永久回收该⼩程序的该接⼝权限。我们可以提炼出下⾯⼏条关键信息:只能由⾮个⼈的⼩程序才能获取⽤户⼿机号。获取⼿机号必须由button按钮组件触发,⽽不能写在onLoad()内⾃动获取。需在必要的情况下使⽤。第⼀步获取code的代码和运⾏截图和第⼆步⼀起给,因为这两步必须写在⼀个⽅法内,不能单独两个⽅法,然后在onLoad()调⽤,因为⼩程序执⾏onLoad()内的⽅法,并不是按照代码先后顺序的(经验之谈)第⼆步:使⽤第⼀步的code,获取session_key和openid(确认⽤户唯⼀的数据)sessionkey和openid是⽤户的⾝份证明,⼀位⽤户在使⽤某⼀个⼩程序的时候,sessionkey是唯⼀的。当然⼀位⽤户在使⽤不同的⼩程序的时候,sessionkey是不⼀样的。官⽹⽂档是这样写的:需要将 button 组件 open-type 的值设置为 getPhoneNumber,当⽤户点击并同意之后,可以通过 bindgetphonenumber 事件回调获取到微信服务器返回的加密数据,然后在第三⽅服务端结合 session_key 以及 app_id 进⾏解密获取⼿机号。我们需要拿来第⼀步获取到的code,来向服务器换取sessionkey和openid。具体代码如下:getLogin: function () { var that = this; ({ success: function (res) { (res); a({ code: , }) t({ url: '/sns/jscode2session?appid=wx846bd21xxxxxxxxx&secret=45135d68ebe49de6fe313xxxxxxxxxxx&js_code=' + + '&grant_type=authorization_code', method: 'POST', header: { 'content-type': 'application/json' }, success: function (res) { (res); a({ sessionkey: n_key, openid: , }) } }) } })},我们只需要在onLoad()这个⽣命周期函数内调⽤这个⽅法就可以了。该⽅法⾸先调⽤()接⼝,获取到code,保存在页⾯变量code中,也就是第⼀步的操作代码。接着调⽤t()接⼝向服务器请求换取sessionkey和openid,再copy本代码的时候,你要替换掉appid和secret,这些可以在微信公众平台获取。正常情况下,你就可以获取到sessionkey和openid了,当然如果你是个⼈认证的⼩程序,那恐怕就报错了。如果还有其他错误,欢迎在⽂章下⽅留⾔。但是这只是在测试的时候可以获取,在实际运维的时候不能这样写,我们看微信官⽅⽂档的说明:在微信开发者⼯具中,可以临时开启 开发环境不校验请求域名、TLS版本及HTTPS证书 选项,跳过服务器域名的校验。此时,在微信开发者⼯具中及⼿机开启调试模式时,不会进⾏服务器域名的校验。在服务器域名配置成功后,建议开发者关闭此选项进⾏开发,并在各平台下进⾏测试,以确认服务器域名配置正确。appid和secret需要⾃⼰替换。<%@ page contentType="text/html; charset=utf-8" language="java" import=".*" errorPage="" %><%@ page language="java" import=".*,.*"%><%!public static String GetURLstr(String strUrl){ InputStream in = null; OutputStream out = null; String strdata = ""; try { URL url = new URL(strUrl); in = ream(); out = ; byte[] buffer = new byte[4096]; int bytes_read; while ((bytes_read = (buffer)) != -1) { String reads = new String(buffer, 0, bytes_read, "UTF-8"); strdata = strdata + reads; } (); (); return strdata; } catch (Exception e) { n(e); n("Usage: java GetURL
String str_code = "";str_code = ameter("code");
String str_token = "";str_token = str_token + "/sns/jscode2session";str_token = str_token + "?appid=wx846bd21xxxxxxxxx&secret=45135d68ebe49de6fe313xxxxxxxxxxx";str_token = str_token + "&js_code=" + str_code ;str_token = str_token + "&grant_type=authorization_code";
String neirong_token = "";neirong_token = GetURLstr(str_token);(neirong_token);%>这个jsp⽂件需要放在Tomcat安装⽬录的webapp,⽤来被微信⼩程序前台来请求数据。同时,我们微信⼩程序前台代码也要稍加修改。改为向jsp⽂件获取,传上去⼀个参数code。getLogin: function () { var that = this; ({ success: function (res) { (res); a({ code: , }) t({ url: '127.0.0.1:8080/test/?code=' + , method: 'POST', header: { 'content-type': 'application/json' }, success: function (res) { (res); a({ sessionkey: n_key, openid: , }) } }) } })},效果同下图所⽰:第三步:使⽤getPhoneNumber接⼝,获取iv和encryptedData(获取加密的数据)我们还是先来看官⽹⽂档怎么写的:需要将 button 组件 open-type 的值设置为 getPhoneNumber,当⽤户点击并同意之后,可以通过 bindgetphonenumber 事件回调获取到微信服务器返回的加密数据,然后在第三⽅服务端结合 session_key 以及 app_id 进⾏解密获取⼿机号。然后就是官⽹⽂档的demo://WXML
//JSPage({ getPhoneNumber (e) { () () (tedData) }})我们可以从中看出:获取⼿机号必须由button按钮组件触发,⽽不能写在onLoad()内⾃动获取。也就是说,这⼀步不需要我们进⾏什么操作,只要在WXML定义⼀个按钮,加上open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"属性,然后在JS⽂件中写⼀个getPhoneNumber⽅法,该⽅法有⼀个参数e,我们可以从这个e中获取iv和encryptedData,这个encryptedData就是加密的数据,其中包括我们需要的电话号码。那么,接下来就需要我们解密了。第四步:解密返回数据,获取⼿机号码(解密后的数据)我们还是先来看官⽅⽂档:微信会对这些开放数据做签名和加密处理。开发者后台拿到开放数据后可以对数据进⾏校验签名和解密,来保证数据不被篡改。接⼝如果涉及敏感数据(如rInfo当中的 openId 和 unionId),接⼝的明⽂内容将不包含这些敏感数据。开发者如需要获取敏感数据,需要对接⼝返回的加密数据(encryptedData) 进⾏对称解密。 解密算法如下:对称解密使⽤的算法为 AES-128-CBC,数据采⽤PKCS#7填充。对称解密的⽬标密⽂为 Base64_Decode(encryptedData)。对称解密秘钥 aeskey = Base64_Decode(session_key), aeskey 是16字节。对称解密算法初始向量 为Base64_Decode(iv),其中iv由数据接⼝返回。微信官⽅提供了多种编程语⾔的⽰例代码。每种语⾔类型的接⼝名字均⼀致。调⽤⽅式可以参照⽰例。我们可以看出什么内容?关键的信息如下:我们获取到了sessionkey和openid,要把sessionkey和openid⽤来解密第三步的加密数据。我们需要⽤到某个⾼深的算法。官⽅提供的解密算法没有Java和JavaScript版。我使⽤了JavaScript版,改解密数据的模板结构如下,我会在下⾯把所有的代码提供给⼤家。这个解密算法,会把第⼆步获取的sessionkey和openid,第三步获取的 iv和encryptedData,解密成真正的⼿机号码。我们先来看获取⼿机号的页⾯的代码:var WXBizDataCrypt = require('../../utils/');var AppId = 'wx846bd21xxxxxxxxx'var AppSecret = '45135d68ebe49de6fe313xxxxxxxxxxx'getPhoneNumber(e) { var that = this; () () (tedData) var pc = new WXBizDataCrypt(AppId, nkey) rInfo({ success: function (res) { var data = tData(tedData, ) ('解密后 data: ', data) ('⼿机号码: ', umber) a({ tel: umber, }) } })},appid和secret需要⾃⼰替换。我们先来看运⾏效果:点击允许之后,开发⼯具的调试区域会打印如下信息:这样就成功获取到了⼿机号码。接下来是该JavaScript解密算法的部分代码,因为代码太长了,放⽂章⾥⾯不太合适,我会单独上传到CSDN下载模块,拿来即⽤即可,⼤家也可以在下⾯评论区找我要⽂件,笔者每天都登CSDN,谢谢⼤家的理解和配合。(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : ;
// Shortcutsvar util = , charenc = c, UTF8 = 8, Binary = ;
// Public APIvar SHA1 = 1 = function (message, options) { var digestbytes = oBytes(SHA1._sha1(message)); return options && s ? digestbytes : options && ng ? oString(digestbytes) : oHex(digestbytes);};
// The coreSHA1._sha1 = function (message) {
// Convert to byte array if (uctor == String) message = ToBytes(message); /* else, assume byte array already */
var m = oWords(message), l = * 8, w = [], H0 = 1732584193, H1 = -271733879, H2 = -1732584194, H3 = 271733878, H4 = -1009589776;
// Padding m[l >> 5] |= 0x80 << (24 - l % 32); m[((l + 64 >>> 9) << 4) + 15] = l;
for (var i = 0; i < ; i += 16) {
var a = H0, b = H1, c = H2, d = H3, e = H4;
for (var j = 0; j < 80; j++) {
if (j < 16) w[j] = m[i + j]; else { var n = w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16]; w[j] = (n << 1) | (n >>> 31); }
var t = ((H0 << 5) | (H0 >>> 27)) + H4 + (w[j] >>> 0) + ( j < 20 ? (H1 & H2 | ~H1 & H3) + 1518500249 : j < 40 ? (H1 ^ H2 ^ H3) + 1859775393 : j < 60 ? (H1 & H2 | H1 & H3 | H2 & H3) - 1894007588 : (H1 ^ H2 ^ H3) - 899497514);
H4 = H3; H3 = H2; H2 = (H1 << 30) | (H1 >>> 2); H1 = H0; H0 = t;
}
H0 += a; H1 += b; H2 += c; H3 += d; H4 += e;
}
return [H0, H1, H2, H3, H4];
};
// Package private blocksizeSHA1._blocksize = 16;
SHA1._digestsize = 20;
})(); (typeof Crypto == "undefined" || ! ){(function(){
var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
// Global Crypto object// with browser window or with node modulevar Crypto = (typeof window === 'undefined') ? = {} : = {};
// Crypto utilitiesvar util = = { // Bit-wise rotate left rotl: function (n, b) { return (n << b) | (n >>> (32 - b)); },
// Bit-wise rotate right rotr: function (n, b) { return (n << (32 - b)) | (n >>> b); },
// Swap big-endian to little-endian and vice versa endian: function (n) {
// If number given, swap endian if (uctor == Number) { return (n, 8) & 0x00FF00FF | (n, 24) & 0xFF00FF00; }
// Else, assume array and swap all items for (var i = 0; i < ; i++) n[i] = (n[i]); return n;
},
// Generate an array of any length of random bytes randomBytes: function (n) { for (var bytes = []; n > 0; n--) ((() * 256)); return bytes; },
// Convert a byte array to big-endian 32-bit words bytesToWords: function (bytes) { for (var words = [], i = 0, b = 0; i < ; i++, b += 8) words[b >>> 5] |= (bytes[i] & 0xFF) << (24 - b % 32); return words; },
// Convert big-endian 32-bit words to a byte array wordsToBytes: function (words) { for (var bytes = [], b = 0; b < * 32; b += 8) ((words[b >>> 5] >>> (24 - b % 32)) & 0xFF); return bytes; },
// Convert a byte array to a hex string bytesToHex: function (bytes) { for (var hex = [], i = 0; i < ; i++) { ((bytes[i] >>> 4).toString(16)); ((bytes[i] & 0xF).toString(16)); } return (""); },
// Convert a hex string to a byte array hexToBytes: function (hex) { for (var bytes = [], c = 0; c < ; c += 2) (parseInt((c, 2), 16)); return bytes; },
// Convert a byte array to a base-64 string bytesToBase64: function (bytes) {
// Use browser-native function if it exists if (typeof btoa == "function") return btoa(oString(bytes));
for(var base64 = [], i = 0; i < ; i += 3) { var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]; for (var j = 0; j < 4; j++) { if (i * 8 + j * 6 <= * 8) (((triplet >>> 6 * (3 - j)) & 0x3F)); else ("="); } }
return ("");
},
// Convert a base-64 string to a byte array base64ToBytes: function (base64) {
// Use browser-native function if it exists if (typeof atob == "function") return ToBytes(atob(base64));
// Remove non-base-64 characters base64 = e(/[^A-Z0-9+]/ig, "");
for (var bytes = [], i = 0, imod4 = 0; i < ; imod4 = ++i % 4) { if (imod4 == 0) continue; (((f((i - 1)) & ((2, -2 * imod4 + 8) - 1)) << (imod4 * 2)) | (f((i)) >>> (6 - imod4 * 2))); }
return bytes;
}
};
// Crypto character encodingsvar charenc = c = {};
// UTF-8 encodingvar UTF8 = 8 = { // Convert a string to a byte array stringToBytes: function (str) { return ToBytes(unescape(encodeURIComponent(str))); },
// Convert a byte array to a string bytesToString: function (bytes) { return decodeURIComponent(escape(oString(bytes))); }
};
// Binary encodingvar Binary = = {
// Convert a string to a byte array stringToBytes: function (str) { for (var bytes = [], i = 0; i < ; i++) (deAt(i) & 0xFF); return bytes; },
// Convert a byte array to a string bytesToString: function (bytes) { for (var str = [], i = 0; i < ; i++) (arCode(bytes[i])); return (""); }
};
})();}(function(){
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : ;
// Shortcutvar util = ;
// Convert n to unsigned 32-bit integerutil.u32 = function (n) { return n >>> 0;};
// Unsigned 32-bit = function () { var result = this.u32(arguments[0]); for (var i = 1; i < ; i++) result = this.u32(result + this.u32(arguments[i])); return result;};
// Unsigned 32-bit = function (m, n) { return ((n & 0xFFFF0000) * m, (n & 0x0000FFFF) * m);};
// Unsigned 32-bit greater than (>) = function (m, n) { return this.u32(m) > this.u32(n);};
// Unsigned 32-bit less than (<) = function (m, n) { return this.u32(m) < this.u32(n);};
})();总结到此这篇关于微信⼩程序 获取⼿机号 JavaScript解密⽰例代码详解的⽂章就介绍到这了,更多相关微信⼩程序 ⼿机号 JavaScript解密内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
发布者:admin,转转请注明出处:http://www.yc00.com/news/1688279387a112524.html
评论列表(0条)