跟我一起学微信之微信接入以及access_token的获取
昨天1块钱买了一个阿里的ECS,一个月是的使用时间。好了,现在可以用它来研究一下微信。之前自己有搞过一个微信公众账号,好久没去弄了,之前也没怎么好好的研究,现在就正式开始吧。至于配置服务器啥的,我就不说了。首先你要自己去申请一个公用测试账号,这样的话权限会比较多。填写你的URL以及TOKEN就行了。我是选择的tp5框架,在index模块下添加了一个Access.php这个文件来验证注册:
1 <?php 2 // +---------------------------------------------------------------------- 3 // | snake 4 // +---------------------------------------------------------------------- 5 // | Copyright (c) 2016~2022 http://baiyf.cn All rights reserved. 6 // +---------------------------------------------------------------------- 7 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) 8 // +---------------------------------------------------------------------- 9 // | Author: NickBai <1902822973@qq.com> 10 // +---------------------------------------------------------------------- 11 namespace app\index\controller; 12 13 use think\Controller; 14 15 class Access extends Controller 16 { 17 public $token = 'weixin'; 18 public function index() 19 { 20 $echoStr = input('param.echostr'); 21 //valid signature , option 22 if( $this->checkSignature() ){ 23 echo $echoStr; 24 exit; 25 } 26 } 27 28 public function responseMsg() 29 { 30 //get post data, May be due to the different environments 31 $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; 32 33 //extract post data 34 if (!empty($postStr)){ 35 /* libxml_disable_entity_loader is to prevent XML eXternal Entity Injection, 36 the best way is to check the validity of xml by yourself */ 37 libxml_disable_entity_loader(true); 38 $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); 39 $fromUsername = $postObj->FromUserName; 40 $toUsername = $postObj->ToUserName; 41 $keyword = trim($postObj->Content); 42 $time = time(); 43 $textTpl = "<xml> 44 <ToUserName><![CDATA[%s]]></ToUserName> 45 <FromUserName><![CDATA[%s]]></FromUserName> 46 <CreateTime>%s</CreateTime> 47 <MsgType><![CDATA[%s]]></MsgType> 48 <Content><![CDATA[%s]]></Content> 49 <FuncFlag>0</FuncFlag> 50 </xml>"; 51 if(!empty( $keyword )) 52 { 53 $msgType = "text"; 54 $contentStr = "Welcome to wechat world!"; 55 $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr); 56 echo $resultStr; 57 }else{ 58 echo "Input something..."; 59 } 60 61 }else { 62 echo "test,,,,"; 63 exit; 64 } 65 } 66 67 private function checkSignature() 68 { 69 70 $param = input('param.'); 71 72 $signature = $param["signature"]; 73 $timestamp = $param["timestamp"]; 74 $nonce = $param["nonce"]; 75 76 $tmpArr = array( $this->token, $timestamp, $nonce ); 77 // use SORT_STRING rule 78 sort($tmpArr, SORT_STRING); 79 $tmpStr = implode( $tmpArr ); 80 $tmpStr = sha1( $tmpStr ); 81 82 if( $tmpStr == $signature ){ 83 return true; 84 }else{ 85 return false; 86 } 87 } 88 89 }
根据官方给的例子直接改写了一点,这边不做过多的解释。我的URL是这样填写的 http://wx.baiyf.com/index/Access , TOKEN值是: weixin,提交提示成功,就代表接入成功了,否则会报出接入失败!自己看一下原因。
下面来进入第二步,获取access_token,什么是access_token呢,看一下官方的解释:access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。
由此可以看出access_token还是挺重要的。实效是2个小时,但是只要你请求一次,系统都会换一次,每个人每天获取access_token的次数是有限制的。所以在2个小时的有效期内,尽量的利用起来,不要盲目的去重复获取。我采用的是用文件的方式存储这些access_token。同样是TP5框架:其中我在common.php文件中写了获取token的公用方法:
1 <?php 2 // +---------------------------------------------------------------------- 3 // | 微信学习测试 4 // +---------------------------------------------------------------------- 5 // | Copyright (c) 2016~2022 http://baiyf.cn All rights reserved. 6 // +---------------------------------------------------------------------- 7 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) 8 // +---------------------------------------------------------------------- 9 // | Author: NickBai <1902822973@qq.com> 10 // +---------------------------------------------------------------------- 11 // 应用公共文件 12 function getToken( $url ) 13 { 14 if( file_exists(APP_PATH . '/token.log') ){ 15 16 $accData = unserialize( file_get_contents( APP_PATH . '/token.log' ) ); 17 18 if( ( time() - $accData['time'] ) > 7200 ){ 19 $token = setToken( $url ); 20 21 if( 1 != $token['code'] ){ 22 return $token; 23 } 24 25 $token = $token['token']; 26 27 }else{ 28 29 $token = $accData['token']; 30 } 31 32 }else{ 33 34 $token = setToken( $url ); 35 36 if( 1 != $token['code'] ){ 37 return $token; 38 } 39 40 $token = $token['token']; 41 } 42 43 return ['code' => 1, 'token' => $token]; 44 } 45 46 //写入token值 47 function setToken( $url ) 48 { 49 $ch = curl_init($url); //初始化curl 50 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //返回数据不直接输出 51 curl_setopt($ch, CURLOPT_POST, 1); //发送POST类型数据 52 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //SSL 报错时使用 53 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //SSL 报错时使用 54 $contents = curl_exec($ch); //执行并存储结果 55 // var_dump(curl_error($ch)); //获取失败是使用(采集错误提示) 56 curl_close($ch); 57 58 $res = json_decode( $contents, true ); 59 if( isset( $res['errcode'] ) ){ 60 return ['code' => $res['errcode'], 'token' => 'invalid appid']; 61 } 62 63 $token = $res['access_token']; 64 65 $putData = [ 66 'token' => $token, 67 'time' => time() 68 ]; 69 70 file_put_contents( APP_PATH . '/token.log', serialize( $putData )); 71 72 return ['code' => 1, 'token' => $token]; 73 }
这样的话,在每个位置都可以方便的获取token值了,你可以在index.php控制器中这样调用:
1 <?php 2 // +---------------------------------------------------------------------- 3 // | 微信学习测试 4 // +---------------------------------------------------------------------- 5 // | Copyright (c) 2016~2022 http://baiyf.cn All rights reserved. 6 // +---------------------------------------------------------------------- 7 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) 8 // +---------------------------------------------------------------------- 9 // | Author: NickBai <1902822973@qq.com> 10 // +---------------------------------------------------------------------- 11 namespace app\index\controller; 12 13 use think\Controller; 14 15 class Index extends Controller 16 { 17 public function index() 18 { 19 print_r( getToken( config('TOKENURL') ) ); 20 } 21 22 }
结果如下:
Array ( [code] => 1 [token] => JI1NTcD6ngiqn52p3iuD0sxfKJ0N44mUAZpZ46MK1aIf3TMUyEoL2hLkbJ-Z8BaenxkYbiM6K1LKl7IIjtI8Y43Hk_RTAD2ksj9zLyBjNIqzE-TGMFa0EL-SLdioBAowTFGhAGABNO )
可以看到我的很多文件都采取的配置模式,因为一些秘钥都是固定的,你可以在config.php文件中像我这样去配置:
1 <?php 2 // +---------------------------------------------------------------------- 3 // | 微信学习测试 4 // +---------------------------------------------------------------------- 5 // | Copyright (c) 2016~2022 http://baiyf.cn All rights reserved. 6 // +---------------------------------------------------------------------- 7 // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) 8 // +---------------------------------------------------------------------- 9 // | Author: NickBai <1902822973@qq.com> 10 // +---------------------------------------------------------------------- 11 12 return [ 13 14 // +---------------------------------------------------------------------- 15 // | 应用设置 16 // +---------------------------------------------------------------------- 17 'APPID' => '', //你的appid 18 'APPSECRET' => '', //你的appsecret 19 'TOKENURL' => 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid= YOURAPPID &secret= YOUR APPSECRET', 20 ];