微信開發公衆號
一、接入概述
1.開始前的準備
接入微信公衆平臺開發,開發者需要按照如下步驟完成:
-
1、填寫服務器配置
-
2、驗證服務器地址的有效性
-
3、依據接口文檔實現業務邏輯
登錄微信公衆平臺,找到 開發-》基本配置-》服務器配置
然後需要配置好服務器環境,域名需要備案,並且端口必須是80或者443.
比如使用php,那麼需要將你填寫的服務器地址導向認證文件,認證寫法官方給了例子,下面是我的寫法:
<?php
/**
* Created by PhpStorm.
* User: ycp
* Date: 2018/4/22
* Time: 21:07
*/
namespace App\Http\Controllers\Weixin;
/**
* wechat php test
*/
//define your token
define("TOKEN", "ycp");
class TestController
{
public function test()
{
$this->valid();
}
public function valid()
{
$echoStr = $_GET["echostr"];
//valid signature , option
if($this->checkSignature()){
echo $echoStr;
exit;
}
}
public function responseMsg()
{
//get post data, May be due to the different environments
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
//extract post data
if (!empty($postStr)){
/* libxml_disable_entity_loader is to prevent XML eXternal Entity Injection,
the best way is to check the validity of xml by yourself */
libxml_disable_entity_loader(true);
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$fromUsername = $postObj->FromUserName;
$toUsername = $postObj->ToUserName;
$keyword = trim($postObj->Content);
$time = time();
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[%s]]></MsgType>
<Content><![CDATA[%s]]></Content>
<FuncFlag>0</FuncFlag>
</xml>";
if(!empty( $keyword ))
{
$msgType = "text";
$contentStr = "Welcome to wechat world!";
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
echo $resultStr;
}else{
echo "Input something...";
}
}else {
echo "";
exit;
}
}
private function checkSignature()
{
// you must define TOKEN by yourself
if (!defined("TOKEN")) {
throw new Exception('TOKEN is not defined!');
}
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = TOKEN;
$tmpArr = array($token, $timestamp, $nonce);
// use SORT_STRING rule
sort($tmpArr, SORT_STRING);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );
if( $tmpStr == $signature ){
return true;
}else{
return false;
}
}
}
驗證通過後這個文件就沒什麼用了,主要是讓微信服務器認證我們的服務器。
然後服務器配置點擊啓用,那麼此後公衆號用戶的一切事件,微信服務器接受到之後將會推送到我們自己的服務器,就可以開始開發了。
2.獲取access_token
access_token是公衆號的全局唯一接口調用憑據,公衆號調用各接口時都需使用access_token。開發者需要進行妥善保存。access_token的存儲至少要保留512個字符空間。access_token的有效期目前爲2個小時,需定時刷新,重複獲取將導致上次獲取的access_token失效。
公衆平臺的API調用所需的access_token的使用及生成方式說明:
-
1、建議公衆號開發者使用中控服務器統一獲取和刷新Access_token,其他業務邏輯服務器所使用的access_token均來自於該中控服務器,不應該各自去刷新,否則容易造成衝突,導致access_token覆蓋而影響業務;
-
2、目前Access_token的有效期通過返回的expire_in來傳達,目前是7200秒之內的值。中控服務器需要根據這個有效時間提前去刷新新access_token。在刷新過程中,中控服務器可對外繼續輸出的老access_token,此時公衆平臺後臺會保證在5分鐘內,新老access_token都可用,這保證了第三方業務的平滑過渡;
-
3、Access_token的有效時間可能會在未來有調整,所以中控服務器不僅需要內部定時主動刷新,還需要提供被動刷新access_token的接口,這樣便於業務服務器在API調用獲知access_token已超時的情況下,可以觸發access_token的刷新流程。
公衆號可以使用AppID和AppSecret調用本接口來獲取access_token
。AppID和AppSecret可在“微信公衆平臺-開發-基本配置”頁中獲得(需要已經成爲開發者,且帳號沒有異常狀態)。調用接口時,請登錄“微信公衆平臺-開發-基本配置”提前將服務器IP地址添加到IP白名單中,點擊查看設置方法,否則將無法調用成功。
接口調用請求說明
https請求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
參數說明
參數 | 是否必須 | 說明 |
---|---|---|
grant_type | 是 | 獲取access_token填寫client_credential |
appid | 是 | 第三方用戶唯一憑證 |
secret | 是 | 第三方用戶唯一憑證密鑰,即appsecret |
因爲需要定時獲取,所以可以設置一個定時任務
//獲取access_token並保存到token.txt文件中
public static function build_access_token(){
$ch = curl_init(); //初始化一個CURL對象
curl_setopt($ch, CURLOPT_URL, "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".self::$appId."&secret=".self::$AppSecret);//設置你所需要抓取的URL
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//設置curl參數,要求結果是否輸出到屏幕上,爲true的時候是不返回到網頁中,假設上面的0換成1的話,那麼接下來的$data就需要echo一下。
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);//跳過證書驗證
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 從證書中檢查SSL加密算法是否存在
$data = json_decode(curl_exec($ch));
if($data->access_token){
$token_file = fopen("token.txt","w") or die("Unable to open file!");//打開token.txt文件,沒有會新建
fwrite($token_file,$data->access_token);//重寫tken.txt全部內容
fclose($token_file);//關閉文件流
}else{
echo $data->errmsg;
}
curl_close($ch);
}
//設置定時器,每兩小時執行一次build_access_token()函數獲取一次access_token
public static function set_interval(){
ignore_user_abort();//關閉瀏覽器仍然執行
set_time_limit(0);//讓程序一直執行下去
$interval = 7200;//每隔一定時間運行
do{
self::build_access_token();
sleep($interval);//等待時間,進行下一次操作。
}while(true);
}
//讀取token
public static function read_token(){
$token_file = fopen("token.txt", "r") or die("Unable to open file!");
$rs = fgets($token_file);
fclose($token_file);
return $rs;
}
然後每次都可以使用
class TestController
{
public function __construct()
{
$this->access_token = self::read_token();
}
public function test()
{
echo $this->access_token;
}
//讀取token
public static function read_token(){
$token_file = fopen("token.txt", "r") or die("Unable to open file!");
$rs = fgets($token_file);
fclose($token_file);
return $rs;
}
}