PHP实现微信公众号验证Token的示例代码


Posted in PHP onDecember 16, 2019
  • 难度水平:初中级
  • 适用人群:对微信公众号开发有认知跟实践的童鞋
  • 阅读时间:8分钟

缘起

很久之前做过一次公众号的开发,当时就遇到了一个验证的小坑,但是由于时间紧任务急处理完了也就没在意,可谁知最近刚刚上马一个新的公众号项目又遇到了同样的小坑,痛定思痛决定奋笔疾书留下痕迹,省的以后再次忘记了。?

开始验证

首先来一张胜过千言万语的图,说明我们要验证的目标:

PHP实现微信公众号验证Token的示例代码

然后开始扫坑。先扫个盲,微信验证的目的就是你来证明你的服务器地址的有效性,所以带着这个目的我们来看看下面这些问题:

  • URL地址怎么写
  • 纯PHP的代码怎么写
  • Laravel的代码怎么写
  • 常见的坑是什么

URL地址怎么写

这个地址可以是路由地址也可以是文件地址:

路由地址形式:
https://mydomain.com/wx,
https://mydomain.com/auth/wx,
https://mydomain.com/utility/wx

文件地址形式:
https://mydomain.com/mywechat...
https://mydomain.com/auth/myw...
https://mydomain.com/utility/...

敲黑板,划重点:
无论哪种形式都可以,重点是可以直接通过GET或者POST访问到

纯PHP的代码怎么写

通常来说纯代码就是非框架的php代码验证方式,废话少说,直接上酸菜:

/*这个是你自定义的令牌,图片里面Token的位置*/
define("TOKEN", "这个是你自定义的令牌");
/*初始化当前的类*/
$wechatObj = new wechatCallbackapiTest();
/*开始验证程序*/
$wechatObj->valid();
/**
 * Class WXApiVerify
 */
class WXApiVerify
{
  /**
   * 检测函数输出
   */
  public function valid()
  {
    $echoStr = $_GET['echostr'];
    if($this->checkSignature()){
      echo $echoStr; #坑点,看下面的常见坑介绍
      exit; #一定要停止php运行,避免产生不必要的字串符
    }
  }

  /**
   * 前面检测
   * @return bool
   */
  private function checkSignature()
  {
    #注意: 这里可以不用检验$_GET参数的有效性,因为微信一定会传相关的参数给你的服务器的,你直接开启验证模式即可。
    $signature = $_GET['signature'];
    $timestamp = $_GET['imestamp'];
    $nonce = $_GET['nonce'];
    $token = TOKEN;
    $tmpArr = array($token, $timestamp, $nonce);
    sort($tmpArr, SORT_STRING);
    $tmpStr = implode( $tmpArr );
    $tmpStr = sha1( $tmpStr );
    if( $tmpStr === $signature ){
      return true;
    }else{
      return false;
    }
  }
}

Laravel的代码怎么写

首先,强势插个口播(在使用过TP5,CodeIgniter, CakePHP, Yii, Slim之后,我认为Laravel是目前来说最好的PHP框架,不接受其他任何意见。)
其次,验证代码上面是跟纯PHP大同小异的,唯一的区别是在你处理POST请求的时候一定要让Laravel不要检测CSFR Token,否则会出现错误。

首先,设置路由:

Route::any('wx', [
  'uses' => 'WeChatApp@checkSignature'
]);
#坑点,看下面的常见坑介绍

其次,取消Laravel的CSFR检查:

#去到你的Middlewarel里面找到VerifyCsrfToken.php然后插入下面代码:
protected $except = [
    'wx', #注意这个是你在第一步设置的路由路径,不接受单独的文件路径,太Low逼了
  ];

最后,上酸菜:

#在你对应的Controller里面加入以下函数
  public function checkSignature( Request $request ) {
    $input = $request->all();
    # 一定要抓取4个参数
    $echoStr  = $input[ "echostr" ];
    $signature = $input[ "signature" ];
    $timestamp = $input[ "timestamp" ];
    $nonce   = $input[ "nonce" ];
    # 微信官方验证方式
    $token = env( 'TOKEN' ); #或者用config()函数
    $tmpArr = [ $token, $timestamp, $nonce ];
    sort( $tmpArr, SORT_STRING );
    $tmpStr = implode( $tmpArr );
    $tmpStr = sha1( $tmpStr );
    
    # 打印返回结果
    if( $tmpStr == $signature ){
      return response($echoStr);
    } else{
      return response();
    }
  }

常见的坑是什么

文档坑。有些人看过官方文档之后直接就上代码了,缺忽略了里面的一个参数echostr 随机字符串 而这个恰恰是验证服务器的关键点,你要打印这个返回给微信才能通过验证。但是官方文档说的不够重点。

Laravel路由坑。一定要设置请求为any这样包括(GET跟POST)

Laravel还有一个测试的坑,就是如果你的APP_DEBUG=false如果不是false的话可能会造成抛出多余的字串导致验证失败。

要学会使用微信官方测试工具 https://mp.weixin.qq.com/debug/ 选择消息接口测试文本消息接口就行。其他的可以看图说话

PHP实现微信公众号验证Token的示例代码

微信UI的坑。在你通过上面的测试后,并不真正代表你启用了服务器。而是在你保存后要点击启用,然后看到红色 停用 才真正的是真正的启用了。

白名单坑。你一定要去到微信的安全中心设置你的服务器的白名单.否则之后的开发工作会有阻碍。

公众号设置坑。你一定要去微信的公众号设置里面加入你的:

  • 业务域名
  • JS接口安全域名
  • 网页授权域名

结语

微信开发有挑战,细心最关键。遇到问题不要慌,来看哥文章。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
十天学会php之第三天
Oct 09 PHP
Win2003服务器安全加固设置--进一步提高服务器安全性
May 23 PHP
php 面试碰到过的问题 在此做下记录
Jun 09 PHP
使用淘宝IP库获取用户ip地理位置
Oct 27 PHP
destoon会员注册提示“数据校验失败(2)”解决方法
Jun 21 PHP
php版银联支付接口开发简明教程
Oct 14 PHP
PHP三种方式实现链式操作详解
Jan 21 PHP
使用PHPStorm+XDebug搭建单步调试环境
Nov 19 PHP
PHP基于回溯算法解决n皇后问题的方法示例
Nov 07 PHP
PHP实现获取url地址中顶级域名的方法示例
Jun 05 PHP
PHP开启目录引索+fancyindex漂亮目录浏览带搜索功能
Sep 23 PHP
解决在Laravel 中处理OPTIONS请求的问题
Oct 11 PHP
浅析PHP中的 inet_pton 网络函数
Dec 16 #PHP
Laravel等框架模型关联的可用性浅析
Dec 15 #PHP
php获取是星期几的的一些常用姿势
Dec 15 #PHP
Yii2框架中一些折磨人的坑
Dec 15 #PHP
关于Yii2框架跑脚本时内存泄漏问题的分析与解决
Dec 01 #PHP
详解no input file specified 三种解决方法
Nov 29 #PHP
设定php简写功能的方法
Nov 28 #PHP
You might like
php自动加载autoload机制示例分享
2014/02/20 PHP
php中数据库连接方式pdo和mysqli对比分析
2015/02/25 PHP
php使用Jpgraph绘制简单X-Y坐标图的方法
2015/06/10 PHP
YII CLinkPager分页类扩展增加显示共多少页
2016/01/29 PHP
thinkPHP自动验证机制详解
2016/12/05 PHP
laravel-admin 在列表页添加自定义按钮的例子
2019/09/30 PHP
用roll.js实现的图片自动滚动+鼠标触动的特效
2007/03/18 Javascript
jQuery autocomplete插件修改
2009/04/17 Javascript
Javascript 日期对象Date扩展方法
2009/05/30 Javascript
JavaScript的类型简单说明
2010/09/03 Javascript
JavaScript类型转换方法及需要注意的问题小结(挺全面)
2010/11/11 Javascript
各浏览器中querySelector和querySelectorAll的实现差异分析
2012/05/23 Javascript
jQuery中设置form表单中action值的实现方法
2016/05/25 Javascript
Node.js中用D3.js的方法示例
2017/01/16 Javascript
利用策略模式与装饰模式扩展JavaScript表单验证功能
2017/02/14 Javascript
javascript中mouseenter与mouseover的异同
2017/06/06 Javascript
微信小程序 上传头像的实例详解
2017/10/27 Javascript
axios向后台传递数组作为参数的方法
2018/08/11 Javascript
Nuxt升级2.0.0时出现的问题(小结)
2018/10/08 Javascript
JavaScript使用表单元素验证表单的示例代码
2019/08/20 Javascript
laydate只显示时分 不显示秒的功能实现方法
2019/09/28 Javascript
Vue使用鼠标在Canvas上绘制矩形
2020/12/24 Vue.js
[37:29]完美世界DOTA2联赛PWL S2 LBZS vs Forest 第二场 11.19
2020/11/19 DOTA
Python日期时间对象转换为字符串的实例
2018/06/22 Python
python 根据时间来生成唯一的字符串方法
2019/01/14 Python
python如何从文件读取数据及解析
2019/09/19 Python
解决安装新版PyQt5、PyQT5-tool后打不开并Designer.exe提示no Qt platform plugin的问题
2020/04/24 Python
HTML5制作3D爱心动画教程 献给女友浪漫的礼物
2014/11/05 HTML / CSS
html5调用app分享功能示例(WebViewJavascriptBridge)
2018/03/21 HTML / CSS
社区学习十八大感想
2014/01/22 职场文书
充分就业社区汇报材料
2014/05/07 职场文书
先进事迹材料怎么写
2014/12/30 职场文书
2015年会计人员工作总结
2015/05/22 职场文书
python opencv常用图形绘制方法(线段、矩形、圆形、椭圆、文本)
2021/04/12 Python
能用CSS实现的就不要麻烦JavaScript了
2021/10/05 HTML / CSS
教你如何让spark sql写mysql的时候支持update操作
2022/02/15 MySQL