当前位置: 首页 > 编程日记 > 正文

微信小程序获取用户手机号,后端php实现 (前后端完整代码附效果图)

微信小程序开发交流qq群   173683895

   承接微信小程序开发。扫码加微信。

如图:

小程序代码:

第一步,登录,获取用户的 session_key;

第二步,点击按钮调用 bindgetphonenumber 事件,通过该事件得到 encryptedData 和 iv

第三步,把session_key,encryptedData 和 iv 传递给后端解密得到用户的手机号信息

文章结尾有我的小程序util.js文件。

登录代码:(我是在app.js 里面统一封装的登录模块,如果有自己的登录模块,可以无视这段代码,把session_key放到第二段代码就可以)

//app.js
const util = require('./utils/util.js');
App({onLaunch: function() {var that = this;// wx.loginthat.login = (resolve) => {wx.login({success: (res) => {if (res.code) {that.loginRequest(res.code, resolve);}},})}// session定时器that.sessionIsExpire = (resolve) => {const session = wx.getStorageSync('session_key');const deadLine = wx.getStorageSync('deadline');const nowDate = new Date().getTime();if (session && deadLine) {if (nowDate - deadLine >= 1000 * 60 * 60 * 24) {that.login(resolve)} else {wx.checkSession({success() {// session_key 未过期,并且在本生命周期一直有效resolve(session)},fail() {// session_key 已经失效,需要重新执行登录流程that.login(resolve)}})}} else {that.login(resolve)}}// 获取sessionthat.pro_getSession = new Promise((resolve) => {that.sessionIsExpire(resolve)})// 请求login.do接口得到sessionthat.loginRequest = (code, resolve) => {var url = '/login.php';var data = {code}util.request(url, 'post', data, '', (res) => {console.log('登录了')if (res.data.success == true) {const session = res.session_key;resolve(session)wx.setStorageSync('openid', res.openid);wx.setStorageSync('session_key', session);wx.setStorageSync('deadline', new Date().getTime())} else {resolve(1)}}, (fail) => {resolve(1)})}},globalData: {userInfo: null}
})

小程序代码片段2: 获取手机号页面的代码

      <button class="motto-font" open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">获取手机号</button>
// 获取手机号码getPhoneNumber: function (e) {console.log(e)if (e.detail.errMsg == 'getPhoneNumber:fail') {console.log(ErrMsg);that.showToast_fail('未获取到手机号码');return false;} else if (e.detail.iv == undefined || !e.detail.iv) {that.showToast_fail('授权失败');return false;} else {// 解密手机号接口var url = "/getTelNumber.php";var params = {session_key: wx.getStorageSync('session_key'),encryptedData: e.detail.encryptedData,iv: e.detail.iv};util.request(url, 'post', params, '', (res) => {that.setData({phone: res.data.phoneNumber,})wx.reLaunch({url: '../index/index',})}, function () {that.showToast_fail('获取手机号失败');})}},

后端实现代码:

登录接口如图

login.php代码 (这个接口返回的是一个JSON对象)

<?phpheader("Content-Type:text/html;charset=utf8"); header("Access-Control-Allow-Origin: *"); //解决跨域header('Access-Control-Allow-Methods:POST');// 响应类型  header('Access-Control-Allow-Headers:*'); // 响应头设置 error_reporting(E_ALL);$code = $_POST['code'];$url='https://api.weixin.qq.com/sns/jscode2session?appid=wx4d7fcc145ca8013b&secret=c58ac54c1bf4c2de7c07221e547a4218&js_code='.$code.'&grant_type=authorization_code';$html = file_get_contents($url);print($html);
?>

getTelNumber.php代码如图

代码:

<?phpheader("Content-Type:text/html;charset=utf8"); header("Access-Control-Allow-Origin: *"); //解决跨域header('Access-Control-Allow-Methods:POST');// 响应类型  header('Access-Control-Allow-Headers:*'); // 响应头设置 $appid = 'wx4d7fcc145ca8013b';$sessionKey = $_POST['session_key'];$encryptedData = $_POST['encryptedData'];$iv = $_POST['iv'];include_once "wxBizDataCrypt.php";$data = '';$pc = new WXBizDataCrypt($appid, $sessionKey);$errCode = $pc->decryptData($encryptedData, $iv, $data );if ($errCode == 0) {print($data . "\n");} else {print($errCode . "\n");}
?>

这里有引用到两个文件,放到相同的目录下就行

wxBizDataCrypt.php

<?php/*** 对微信小程序用户加密数据的解密示例代码.** @copyright Copyright (c) 1998-2014 Tencent Inc.*/include_once "errorCode.php";class WXBizDataCrypt
{private $appid;private $sessionKey;/*** 构造函数* @param $sessionKey string 用户在小程序登录后获取的会话密钥* @param $appid string 小程序的appid*/public function __construct( $appid, $sessionKey){$this->sessionKey = $sessionKey;$this->appid = $appid;}/*** 检验数据的真实性,并且获取解密后的明文.* @param $encryptedData string 加密的用户数据* @param $iv string 与用户数据一同返回的初始向量* @param $data string 解密后的原文** @return int 成功0,失败返回对应的错误码*/public function decryptData( $encryptedData, $iv, &$data ){if (strlen($this->sessionKey) != 24) {return ErrorCode::$IllegalAesKey;}$aesKey=base64_decode($this->sessionKey);if (strlen($iv) != 24) {return ErrorCode::$IllegalIv;}$aesIV=base64_decode($iv);$aesCipher=base64_decode($encryptedData);$result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);$dataObj=json_decode( $result );if( $dataObj  == NULL ){return ErrorCode::$IllegalBuffer;}if( $dataObj->watermark->appid != $this->appid ){return ErrorCode::$IllegalBuffer;}$data = $result;return ErrorCode::$OK;}}

errorCode.php

<?php/*** error code 说明.* <ul>*    <li>-41001: encodingAesKey 非法</li>*    <li>-41003: aes 解密失败</li>*    <li>-41004: 解密后得到的buffer非法</li>*    <li>-41005: base64加密失败</li>*    <li>-41016: base64解密失败</li>* </ul>*/
class ErrorCode
{public static $OK = 0;public static $IllegalAesKey = -41001;public static $IllegalIv = -41002;public static $IllegalBuffer = -41003;public static $DecodeBase64Error = -41004;
}?>

小程序util.js文件

const formatTime = date => {const year = date.getFullYear()const month = date.getMonth() + 1const day = date.getDate()const hour = date.getHours()const minute = date.getMinutes()const second = date.getSeconds()return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
// 网络请求
const request = function(url, method, data, msg, succ, fail, com) {// 小程序顶部显示Loadingwx.showNavigationBarLoading();if (msg != "") {wx.showLoading({title: msg})}wx.request({url: 'http://localhost/shige/minP'+url,data: data,header: {'content-type': 'application/x-www-form-urlencoded'},method: method,success: res => {if (succ) succ(res);},fail: err => {wx.showToast({title: '网络错误,请稍后再试···',icon:'none'})if (fail) fail(err);},complete: com => {wx.hideNavigationBarLoading();if (msg != "") {wx.hideLoading();}console.log(url + ' 返回的data:', com.data);}})
}
const formatNumber = n => {n = n.toString()return n[1] ? n : '0' + n
}module.exports = {formatTime: formatTime,request: request
}

相关文章:

pytorch与keras_Keras vs PyTorch:如何通过迁移学习区分外星人与掠食者

pytorch与kerasby Patryk Miziuła通过PatrykMiziuła Keras vs PyTorch&#xff1a;如何通过迁移学习区分外星人与掠食者 (Keras vs PyTorch: how to distinguish Aliens vs Predators with transfer learning) This article was written by Piotr Migdał, Rafał Jakubanis…

Ubuntu 16.04安装QQ(不一定成功)

注意1&#xff1a;如果是刚新装的系统&#xff0c;可以正常安装&#xff0c;但是&#xff0c;如果你已经装了很多软件&#xff0c;千万不要安装&#xff0c;因为会把系统上一般的依赖包和你之前装的软件全部卸载掉&#xff01;甚至将桌面Dock都会卸载&#xff01;最终只能重装U…

for循环动态的给select标签添加option内容

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 html <select class"form-control selectpicker" name"college" id"eq_num" data-actions-box"true" data-live-search"true" data-live-sea…

Linux下Debug模式启动Tomcat进行远程调试

J2EE开发各类资源下载清单, 史上最全IT资源&#xff0c;点击进入&#xff01; 一&#xff0e; 应用场景 在实际的测试过程中&#xff0c;可能会遇到由于程序执行的不间断性&#xff0c;我们无法构造测试场景来验证某个功能的正确性&#xff0c;只有通过代码级的调试才能验…

guice google_与Google Guice的动手实践

guice googleby Sankalp Bhatia通过Sankalp Bhatia 与Google Guice的动手实践 (A hands-on session with Google Guice) A few months ago, I wrote an article explaining dependency injection. I had mentioned of a follow-up article with a hands-on session of Google …

IQKeyboardManager使用方法

使用方法&#xff1a;将IQKeyboardManager 和 IQSegmentedNextPrevious类文件加进项目中。在AppDelegate文件中写下以下一行代码&#xff1a; [IQKeyBoardManager installKeyboardManager]; 搞定&#xff01; 也可以开启或者关闭keyboard avoiding功能&#xff1a; [IQKeyBoard…

JQ加AJAX 加PHP实现网页登录功能

微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 前端代码 <!DOCTYPE HTML> <html><head><link href"css/style.css" rel"stylesheet" type"text/css" media"all" /><meta http-eq…

web安全简介_Web安全:HTTP简介

web安全简介by Alex Nadalin通过亚历克斯纳达林 Web安全&#xff1a;HTTP简介 (Web Security: an introduction to HTTP) This is part 2 of a series on web security: part 1 was “Understanding The Browser”这是有关网络安全的系列文章的第2部分&#xff1a;第1部分是“…

继承实现的原理、子类中调用父类的方法、封装

一、继承实现的原来 1、继承顺序 Python的类可以继承多个类。继承多个类的时候&#xff0c;其属性的寻找的方法有两种&#xff0c;分别是深度优先和广度优先。 如下的结构&#xff0c;新式类和经典类的属性查找顺序都一致。顺序为D--->A--->E--->B--->C。 class E:…

hdu 5366 简单递推

记f[i]为在长度是i的格子上面至少放一个木桩的方法数。考虑第i个格子&#xff0c;有放和不放两种情况。 1.如果第i个格子放了一个木桩&#xff0c;则i - 1和i - 2格子上面不能放木桩&#xff0c;方案数为&#xff1a;f[i - 3] 1 2.如果第i个格子没有放木桩&#xff0c;则方案数…

git 代理 git_如何不再害怕GIT

git 代理 git了解减少不确定性的机制 (Understanding the machinery to whittle away the uncertainty) 到底什么是Git&#xff1f; (What is Git anyway?) “It’s a version control system.”“这是一个版本控制系统。” 我为什么需要它&#xff1f; (Why do I need it?)…

Python 基础 - Day 2 Assignment - ShoppingCart 购物车程序

作业要求 1、启动程序后&#xff0c;输入用户名密码后&#xff0c;如果是第一次登录&#xff0c;让用户输入工资&#xff0c;然后打印商品列表 2、允许用户根据商品编号购买商品 3、用户选择商品后&#xff0c;检测余额是否够&#xff0c;够就直接扣款&#xff0c;不够就提醒 4…

hdu 1878 欧拉回路

欧拉回路 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10548 Accepted Submission(s): 3849 Problem Description欧拉回路是指不令笔离开纸面&#xff0c;可画过图中每条边仅一次&#xff0c;且可以回到起点…

bootstrap 时间日期日历控件(datetimepicker)附效果图

开发交流QQ群: 173683895 173683895 526474645 人满的请加其它群 效果图 代码 <!DOCTYPE html> <html><head><meta charset"UTF-8"><link href"https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel&q…

如何在您HTML中嵌入视频和音频

by Abhishek Jakhar通过阿比舍克贾卡(Abhishek Jakhar) 如何在您HTML中嵌入视频和音频 (How to embed video and audio in your HTML) HTML allows us to create standards-based video and audio players that don’t require the use of any plugins. Adding video and audi…

html 省份,城市 选择器附效果图

开发交流QQ群: 173683895 173683895 526474645 人满的请加其它群 效果图&#xff1a; 源码&#xff1a; <!DOCTYPE html> <html><head><meta charset"UTF-8"><link href"https://cdn.bootcss.com/bootstrap/3.3.7/css/boots…

机器学习:协方差矩阵

一、统计学的基本概念 统计学里最基本的概念就是样本的均值、方差、标准差。首先&#xff0c;我们给定一个含有n个样本的集合&#xff0c;下面给出这些概念的公式描述&#xff1a; 均值&#xff1a; 标准差&#xff1a; 方差&#xff1a; 均值描述的是样本集合的中间点&#xf…

TemplatedParent 与 TemplateBinding

http://blog.csdn.net/idebian/article/details/8761388转载于:https://www.cnblogs.com/changbaishan/p/4716414.html

避免成为垃圾邮件_如何避免犯垃圾

避免成为垃圾邮件by Yoel Zeldes由Yoel Zeldes 如何避免犯垃圾 (How to avoid committing junk) In the development process, every developer writes stuff they don’t intend to commit and push to the remote server, things like debug prints. It happens to all of u…

[bzoj2333] [SCOI2011]棘手的操作 (可并堆)

//以后为了凑字数还是把题面搬上来吧2333 发布时间果然各种应景。。。 Time Limit: 10 Sec Memory Limit: 128 MB Description 有N个节点&#xff0c;标号从1到N&#xff0c;这N个节点一开始相互不连通。第i个节点的初始权值为a[i]&#xff0c;接下来有如下一些操作&#xff1…

vue.js created函数注意事项

因为created钩子函数是页面一加载完就会调用的函数&#xff0c;所以如果你想在这个组件拿值或者是赋值&#xff0c;很可能this里面能拿到数据&#xff0c;但是如果你用this.赋值的话&#xff0c;控制台或者debugger都会发现this里面有你所想要的数据&#xff0c;但是赋值后就是…

JS删除城市的后缀

开发交流QQ群: 173683895 173683895 526474645 人满的请加其它群 代码 const deleteStr str >{if (str.indexOf("市") ! -1 || str.indexOf("州") ! -1){str str.substring(0, str.length - 1)console.log(删除城市的最后一个字,str)return s…

gatsby_将您的GraphCMS数据导入Gatsby

gatsbyLets set up Gatsby to pull data from GraphCMS.让我们设置Gatsby来从GraphCMS中提取数据。 This will be a walk-through of setting up some basic data on the headless CMS, GraphCMS and then querying that data in Gatsby.这将是在无头CMS&#xff0c;GraphCMS上…

Java学习笔记07--日期操作类

一、Date类 在java.util包中定义了Date类&#xff0c;Date类本身使用非常简单&#xff0c;直接输出其实例化对象即可。 public class T { public static void main(String[] args) { Date date new Date(); System.out.println("当前日期&#xff1a;"date); //当前…

javascript数组集锦

设计数组的函数方法 toString, toLocaleString, valueOf, concat, splice, slice indexOf,lastIndexOf, push, pop, shift, unshift, sort, reverse map, reduce, reduceRight, filter, every, some, forEach 创建数组 数组字面量创建&#xff1a;var arr [val1, val2, val3];…

JS实现HTML标签转义及反转义

开发交流QQ群: 173683895 173683895 526474645 人满的请加其它群 编码反编码 function html_encode(str) { var s ""; if (str.length 0) return ""; s str.replace(/&/g, "&amp;"); s s.replace(/</g, "<")…

喜欢把代码写一行的人_我最喜欢的代码行

喜欢把代码写一行的人Every developer has their favourite patterns, functions or bits of code. This is mine and I use it every day.每个开发人员都有自己喜欢的模式&#xff0c;功能或代码位。 这是我的&#xff0c;我每天都用。 它是什么&#xff1f; (What is it?) …

智能家居APP开发

智能家居APP开发 APP开发技术qq交流群&#xff1a;347072638 前言&#xff0c;随着智能硬件设备的流行&#xff0c;智能家居開始红火&#xff0c;智能家居就是家用电器的智能化。包含智能锁&#xff0c;灯&#xff0c;空调&#xff0c;灯&#xff0c;音箱等等&#xff0c;移动设…

android小技巧(二)

一、如何控制Android LED等&#xff1f;(设置NotificationManager的一些参数) 代码如下: final int ID_LED19871103; NotificationManager nm(NotificationManager)getSystemService(NOTIFICATION_SERVICE); Notification notification new Notification(); notificatio…

JS 验证表单不能为空

开发交流QQ群: 173683895 173683895 526474645 人满的请加其它群 JS 验证表单不能为空的简单demo&#xff0c;先看效果图 实现代码 <!--index.wxml--> <form classform bindsubmitformSubmit bindresetformReset><input namename value{{name}} placeho…