咱們可使用 Laravel 框架爲微信公衆平臺提供一個接口(API),這個接口能夠處理微信發送過來的請求,根據這些請求裏面的帶的內容,你能夠決定怎麼樣作出迴應,好比返回用戶想要查看的內容,處理用戶想要作的事等等。在你的 Laravel 應用程序作出迴應以前,先要判斷一下,這個請求是否是來自微信那裏。這篇文章,咱們就介紹一下怎麼樣判斷請求是否是來自微信,同時也簡單介紹一下 Laravel 這個框架。nginx
微信公衆平臺
首先你要作的是申請微信的公衆賬號,目前分紅兩種,訂閱號,還有服務號。訂閱號普通人就能夠申請,服務號應該須要公司才能申請。服務號比訂閱號可使用的接口多一些,就是服務號有更多的功能。我申請的是訂閱號,若是有必要的話,去註冊個公司,申請一個服務號也行。laravel
假設你已經經過了公衆賬號(訂閱號或服務號),想要成爲微信公衆平臺的開發者,你須要給微信提供一個地址,這個地址就應該是你的應用程序上的某個地址,一下子咱們用 Laravel 去建立這個地址。微信會往你提供的這個地址上發出一個請求,在這個請求裏面,會包含一些內容,你的應用程序的這個地址,應該返回給微信特定的內容,這個內容已經包含在了微信給你發過來的請求裏面,微信收到你的迴應之後,若是肯定是它想要的東西,這樣,你就能夠成爲微信的開發者了。sql
成爲微信開發者
其實經過這個驗證是很是簡單的,你只須要把應用接收到的微信發過來的 echostr 這個東西,給它原樣返回去就好了。微信會發送一個 GET 類型的請求到你填寫的地址上,GET 請求就至關因而用戶直接在瀏覽器地址欄上輸入了你的應用的地址,而後按了一下回車。只不過,這個請求帶了一些額外的東西,在你的應用裏面,你能夠接收到這個請求裏帶的這些東西。在 PHP 裏面,接收到 GET 請求裏的內容,能夠訪問 $_GET 這個超級全局變量。好比微信發過來的 GET 請求裏面,會包含 echostr,要獲得 echostr 對應的內容,能夠這樣:數據庫
$_GET['echostr']
若是拋開 Laravel 框架,單純用原始的 PHP 代碼的話,能夠這樣來經過微信的成爲開發者的驗證:apache
echo $_GET['echostr'];
只須要上面這行代碼。它的意思就是,把微信使用 GET 請求給咱們發送過來的 echostr 裏面的東西輸出出來。假設這行 php 代碼在你提供的地址的根目錄下,名字是 index.php 。編程
而後登陸微信公衆平臺之後,打開 功能 - 高級功能 - 成爲開發者,在這裏,會讓你輸入兩樣東西,一個就是微信要把請求發送到的你的應用的地址,另外一樣東西叫 token ,你能夠隨便怎麼去定義這個 token 的內容,微信會用到你在這個 token裏的填寫的內容去生成最終的簽名,一下子咱們再詳細介紹一下。json
都輸入好之後,點擊 提交,沒有意外的話,你就能夠順利成爲微信公衆平臺的開發者了。
等會兒,前面介紹的方法雖然可讓你成爲開發者,可是咱們並不但願這樣作。想像一下,任何人均可以向你的應用的這個地址發送這樣的 GET 請求。因此, 你須要一種方法驗證一下,發送過來的請求是否是來自微信,由於你不想把用戶相關的內容隨便就響應回去。
驗證請求的來源
微信的服務器會把訂閱你的公衆平臺的用戶發送到你的微信賬號的信息打個包發到你提供的地址上。你的應用程序接收到微信發過來的信息,處理一下,而後再作出一個響應。當你的程序接收到微信發過來的請求的時候,你得驗證一下這個請求是否是從微信那裏發過來的。
這個驗證的過程大概是這樣的,微信向你發送過來的請求裏面,帶着幾樣東西,一個微信會生成加密的簽名(一串加密之後的字符串),還有幾樣其它的東西,你的應用程序能夠接收到這個請求裏面的這些東西的具體的內容,你須要在程序裏面,利用這些東西,加上你在微信後臺填寫的 token ,去本身生成一個加密的簽名,而後再用這簽名跟微信發送過來的簽名進行對比,若是兩個簽名是同樣的,就說明這個請求是來自微信。這樣你就能夠安全的對這個請求作出必要的迴應。
下面,咱們再從技術的角度去解釋一下這個過程。微信在給你發送的請求裏面,會包含三樣東西:
- signature:加密的簽名
- timestamp:時間戳
- nonce:一組隨機的數字
在你第一次提交驗證成爲微信開發者的時候,在這個請求裏面,還會包含另一樣東西:
echostr:一組隨機的字符串
signature
這是微信經過特定的方法生成的一組加密的字符串。生成這個東西,用到了 token(你在微信後臺本身填寫的),timestamp(請求發生的時間),nonce(一組隨機的數字)。微信會把這幾樣東西排一下順序(字典序),再把排序以後的結果拼成一個字符串,再用 sha1 的方法對這個字符串進行加密,加密之後獲得的結果就是這個 signature 。
在咱們本身的應用裏面,也須要用到一樣的方法,去生成一個本身的 signature,再跟微信那頭生成的 signature 對比一下。同樣的話,說明請求是來自微信的。
在後面,咱們再詳細介紹怎麼樣使用代碼去實現這個驗證。下面,咱們去準備一下應用須要的軟硬件。
買一臺服務器
咱們就是簡單測試一下,不過也須要一臺服務器。遲早你得有這麼一臺:)能夠試試國內的阿里雲之類的雲服務器,月付的話,1G 內存的服務器一個月 70 塊上下,先買一個月試一下。能夠本身按照 《CentOS:在阿里雲上運行網站》這個課程本身去配置一下,不過最近阿里雲提供了鏡像市場,雖然沒用過,但以爲想法很是好,就是別人作好的鏡像,你能夠直接用,有免費的,有收費的,這些鏡像通常都擁有配置好的環境,你能夠根據本身的需求選擇適合本身的鏡像。你把鏡像想成是一塊別人的硬盤就好了,硬盤裏面,已經裝好了你須要的東西。
不想麻煩去爲網站備案,能夠選擇香港服務器與國外的服務器,阿里雲最近也推出了香港節點的服務器,運行在上面的網站是不須要備案的。
你的服務器應該能運行 PHP 應用程序,推薦使用 LAMP 環境,Linux + Apache + Mysql + PHP,或者,你喜歡 Nginx ,能夠把 Apahce 換成 Nginx 。注意咱們要用的 Laravel ,須要 PHP 5.4 以上的版本。
Laravel 框架
我據說 Laravel 是一套很是優雅的 PHP 框架,受到了不少很是優秀框架的啓發,好比 Ruby on Rails 。由於 Drupal 8 要來了,它使用了 Symfony 框架,因此就先去看了一下 Symfony ,看介紹的時候說 Laraval 也用到了很多 Symfony 的組件,並且語句優雅,你必定能喜歡上,看到這個廣告語就忍不住去試了一下,打開 Laravel 的網站,我就知道不會錯了。
我是第一次使用框架,以爲 Laravel 很好,用起來特別簡單,瞭解一些 PHP 的基礎,一點數據庫,一點面向對象的編程方法,基本上就能夠去用 Laravel 了。我以爲我們都應該學一套框架,因此,今年打算出一些 Laravel 的基礎課程,目前基本上已經定稿了,出完了 PHP 基礎之後,就把 Laravel 的基礎也製做出來。
PHP 5.5
Laravel 須要使用 PHP 5.4 以上的版本,先確認一下你的服務器上安裝的 PHP 版本,可使用命令 php -v 查看一下。若是 PHP 版本低於 PHP 5.4 ,先把舊版的 PHP 刪除掉,從新安裝新版的 PHP。假設你用的是 CentOS 系統,以前使用的是yum 安裝的 PHP,想要移除如今安裝的 PHP,能夠這樣:
yum remove php-common
而後再從新安裝一下新版本的 PHP,能夠先用 yum 在你的資源庫裏面搜索一下:
yum search php
若是你能看到一些 php55 ... 這樣的東西,說明你能夠直接使用 yum 安裝 PHP5.5 ,若是看不到的話,你須要手工去安裝必要的資源庫,而後再從新試一下。安裝 PHP 還有必要的擴展:
yum install php55u php55u-json php55u-mcrypt php55u-pdo php55u-mysqlnd
再運行一下 php -v 查看一下 PHP 的版本。
準備 Laravel
Laravel 惟一推薦的安裝方式就是使用 Composer,因此你須要先去安裝一下 Composer。安裝完成之後,輸入命令 composer,你應該能夠看到一些命令,說明可使用 Composer。
安裝 Composer
進入到某個目錄裏面,好比你的用戶的主目錄
cd ~
使用 curl 命令去下載 Composer(注:國內訪問速度很慢)
curl -sS https://getcomposer.org/installer | php
完成之後,查看一下目錄裏的東西
ls
你會看到這樣一個文件
composer.phar
輸入命令
php composer.phar
你應該能看到一些命令的幫助信息,不過咱們不但願每次使用 Composer 的時候,都要使用 php 命令去運行它。你能夠把composer.phar 移動到你的系統的環境變量裏面的某個目錄下面。這樣你就能夠在任何地方使用 composer 命令了。查看系統的環境變量,能夠這樣:
echo $PATH
返回的應該是一個目錄的位置的列表,把 composer.phar 放在這裏列出的任意一下目錄的下面就好了。我把 composer.phar放到了 /usr/local/bin 下面。
mv composer.phar /usr/local/bin/composer
再試一次輸入 composer 命令,你應該會看到一些命令的幫助信息。如今, 咱們就可使用 Composer 去安裝 Laravel 了。
安裝 Laravel
有了 Composer 之後,咱們先進入到你想把 Laravel 放到的那個目錄裏面,任何目錄均可以,等會兒咱們再去設置虛擬主機。我打算把它放在這個目錄下面:
/var/www/html/we.ninghao.net
先進入到這個目錄:
cd /var/www/html/we.ninghao.net
而後使用 composer 命令去安裝 Laravel
composer create-project laravel/laravel weixin --prefer-dist
這裏用的是 composer 的 create-project 命令,去建立一個新的項目,建立的項目基於 Laravel 框架,項目的名字是weixin,這個名字你能夠根據本身的需求隨便去命名一下。注意若是你用的是國內的服務器,使用 composer 安裝 Laravel 的過程很是慢,得多忍一下子了。
完成之後,你會看到在目錄裏面,會有一個新的項目目錄,這個目錄的名字就是你在建立 Laravel 項目的時候本身指定的,在我這裏,應該就是 weixin 。
Laravel 配置
使用 Laravel 框架開發應用的時候,你的代碼通常都會放在 app 這個目錄下面。好比應用的配置文件,路由,控制器,視圖,模型等等。先去簡單配置一下 Laravel,進入到 app/config 這個目錄下面。
基本
cd weixin/app/config
編輯一下這個目錄下面的 app.php 這個文件
vim app.php
使用 vim 編輯器,去編輯這個文件,按一下小 i 進入到編輯模式,而後找到 'debug' 這個關鍵詞,把它的值修改爲'true',意思就是開啓應用的調試功能,注意在正式版的應用裏面,須要關掉這個調試功能。
'debug' =>true,
再瀏覽器到 'url' 這個地方,把它的值修改爲你的應用程序的地址,我打算把 we.ninghao.net 指向這個應用,因此能夠這樣:
'url' => 'http://we.ninghao.net',
你要根據本身的需求,修改這個 url 配置選項的值。另外這個配置文件裏面,還有些其它的選項,好比時區,地域等等。
保存並退出這個文件。按下 esc,輸入 wq 並回車。
數據庫
下面,你須要給 Laravel 準備一個數據庫,Laravel 支持不少種數據庫系統,MySQL,Postgres,SQLite,SQL Server。你能夠選擇使用這裏的任意一種數據庫。通常,咱們都是使用 MySQL,先去建立一個 MySQL 數據庫,在命令行裏,能夠直接建立 MySQL 數據庫,或者你可使用圖形工做,好比 PHPMyAdmin,或者 Sequel Pro 。
有了數據庫之後,去打開 Laravel 裏面的數據庫相關的配置文件:
app/config/database.php
找到 mysql 數據庫相關的配置,像下面這樣去修改一下:
'mysql' => array( 'driver' => 'mysql', 'host' => 'localhost', 'database' => '爲 Laravel 準備的數據庫的名字', 'username' => '你的數據庫管理員', 'password' => '你的數據庫管理密碼', 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', ),
完成之後,保存並退出。
權限
下面,咱們還得修改一個目錄的權限(app/storage),你須要給它寫入的權限,通常,咱們能夠把這個目錄的擁有者修改爲你的 Web 服務器使用的用戶,若是你用的是 Apache ,那麼這個用戶有可能就是 apache (CentOS)或者 www-data,具體你須要打開 Apache 的配置文件去看一下(httpd.conf)。若是你用的是 Nginx 服務器,參考這篇文章裏面的修改目錄和文件權限的部分。
修改目錄的擁有者,能夠像這樣:
chown -R apache app/storage
上面這行命令,會把 app 下面的 storage 這個目錄以及它所包含的子目錄的擁有者修改爲 apache ,修改完成之後,能夠查看一下。
ls -la
虛擬主機
到目前爲止,咱們基本完成了 Laravel 部分的配置。下面,咱們要作的是去在服務器裏添加一個虛擬主機,把一個域名綁定到 Laravel 框架裏面的 public 這個目錄上,public 這個目錄裏包含向用戶公開的東西,樣式表,腳本文件,要用到圖片,還包含一個 index.php 。
如何配置虛擬主機取決於你用的 Web 服務器。Nginx 服務器能夠參考這篇文章裏的配置虛擬主機部分。Apache 服務器能夠參考這篇文章配置虛擬主機。
虛擬主機的目錄應該是 Laravel 裏面的 public 這個目錄。好比個人這個目錄是在:
/var/www/html/we.ninghao.net/weixin/public
那麼,上面這個地址,就應該是虛擬主機的主目錄。我爲這個目錄綁定的域名是 we.ninghao.net。配置好之後,在地址裏輸入你的虛擬主機的域名,我這裏就是 http://we.ninghao.net ,你應該會看到 Laravel 框架的默認的首頁,上面有一個 Laravel 的標誌,還有一行文字:You have arrived 。
建立與微信溝通的接口
下面,咱們得去在應用裏面建立一個跟微信溝通的接口,這個接口其實就是在應用裏面的一個地址,這個地址能夠去處理微信的請求,能夠對請求作出相應的響應。Laravel 是一套基於 MVC 架構的框架,因此,處理請求用的是 MVC 裏面的 C 這部分,C = Controller(控制器)。
注:咱們會在 Laravel 基礎課程裏面詳細去介紹 Laravel 裏面的每一個部分。
在 Laravel 裏面,控制器也有同個類型,好比 RESTful 類型的控制器,有 Resource 類型的控制器。我打算用 Resource 類型的控制器去處理微信發過來的請求。可能建立 Resource 類型的控制器有點浪費,由於微信應該只會發送兩種請求 GET 和 POST,因此控制器裏的其它的方法就有點多餘了,不過咱們仍是去建立一個 Resource 類型的控制器,能夠順序演示同樣 Laravel 的 artisan 命令行工具的用法。
建立控制器
先進入到剛纔咱們建立的 Laravel 項目所在的目錄,在我這裏應該是:
/var/www/html/we.ninghao.net/weixin/
而後用 artisan 的 controller:make 命令,去建立一個 Resource 類型的控制器:
php artisan controller:make WeixinController
這條命令建立的控制器的名字是 WeixinController,這條命令會生成一個控制器文件,在你的 app/controllers 目錄下面:
app/controllers/WeixinController.php
路由
有了控制器之後,咱們能夠去添加一條路由,而後讓這個路由使用剛纔建立的那個控制器去處理相應的請求。一條路由就是在應用程序裏面,可能被請求的一個地址。在 Laravel 裏面,全部的路由都在 app/routes.php 這個文件裏面。打開這個文件,而後添加下面這些代碼:
Route::resource('api/v1', 'WeixinController');
上面這行代碼,就是爲應用添加了一條路由。api/v1 ,這是路由的地址,WeixinController 就是處理請求這個地址用到的控制器。由於它是一個 Resource 類型的控制器,因此若是訪問 api/v1 這個地址的話,會用控制器裏面的 index() 這個方法去處理。
過濾器
在控制器的對應的方法裏面,能夠去處理微信的請求。不過在控制器的方法作出響應以前, 咱們要去驗證一下這個請求是否是來自微信。在 Laravel 裏面,能夠去給路由或者控制器去添加過濾器,過濾器的做用就是,在請求以前或者以後去作一些驗證,好比用戶是否是已經登陸了。經過了驗證,纔會作出迴應。在 Laravel 裏面,已經包含了幾個基本的過濾器,它們都是在 app/filters.php 文件裏面定義的。
下面,咱們本身去定義一個過濾器。用這個過濾器過濾掉來源不是微信的請求。打開 app/filters.php 文件,添加下面這幾行代碼:
Route::filter('weixin', function() { // 獲取到微信請求裏包含的幾項內容 $signature = Input::get('signature'); $timestamp = Input::get('timestamp'); $nonce = Input::get('nonce'); // ninghao 是我在微信後臺手工添加的 token 的值 $token = 'ninghao'; // 加工出本身的 signature $our_signature = array($token, $timestamp, $nonce); sort($our_signature, SORT_STRING); $our_signature = implode($our_signature); $our_signature = sha1($our_signature); // 用本身的 signature 去跟請求裏的 signature 對比 if ($our_signature != $signature) { return false; } });
上面這幾行代碼就是去建立了一個叫 weixin 的過濾器,這個過濾器作的事就是,先去獲取到微信請求裏面包含的幾項內容,咱們須要用到這幾個東西,按照微信的方法加工一個本身的 signature ,而後再用這個 signature 去跟在請求裏面包含的signature 去對比,若是不匹配的話,就返回 false 。
在代碼裏用到了 Input::get。它就是 Laravel 裏面 Input 類的 get 方法,用它能夠獲得請求裏面的包含的具體的內容。
下面,咱們能夠把這個過濾器用到 WeixinController 這個控制器上。打開這個控制器,而後添加下面這幾行代碼:
public function __construct() { $this->beforeFilter('weixin', array('on' => 'get|post')); }
它的意思就是,在這個控制器的構造函數(實例化類之後當即執行的函數)裏面,添加了一個叫 weixin 的過濾器,這個過濾器會應用到全部的 get 和 post 類型的請求上。注意這個 weixin 的過濾器是做爲 beforeFilter 添加進來的,也就是在請求以前就要使用這個過濾器。
如今,咱們的 WeixinController 這個控制器就有了 weixin 這個過濾器的保護,任何用 GET 或 POST 方法發送過來的請求,都會先去確認一下這個請求是不是來自微信。
成爲微信開發者
到目前爲止, 咱們已經爲應用建立了一個跟微信溝通的接口(api/v1),當有請求發送到這個接口的時候,會先去驗證一下這個請求是不是來自微信。若是是的話,纔會使用相應的方法去處理這個請求。
成爲微信開發者,咱們須要在微信公衆平臺的後臺,提供一個地址,還有一個 token 。token 我設置成了 ninghao。 如今咱們能夠把 url 設置成建立的這個接口的地址,在我這裏應該就是:
http://we.ninghao.net/api/v1
訪問 api/v1 這個地址的時候,是由 WeixinController 這個控制器裏面的 index() 方法去處理。因此,咱們須要在這個方法裏,去返回微信發送過來的 echostr ,這樣才能經過驗證,成爲微信公衆平臺的開發者。
public function index() { return Input::get('echostr'); }
這樣,WeixinController 這個控制器,如今看起來應該是這個樣子的:
class WeixinController extends \BaseController { public function __construct() { $this->beforeFilter('weixin', array('on' => 'get|post')); } /** * Display a listing of the resource. * * @return Response */ public function index() { return Input::get('echostr'); } // .......... }
下一步
這篇文章裏咱們介紹了怎麼樣成爲微信公衆平臺的開發者,怎麼樣驗證請求是否是來自微信,除此之外,還不能作什麼。下一步要作的就是,去設置一些方法,去處理訂閱的用戶從微信裏發送的信息,根據這些信息的內容,咱們的應用須要作出不一樣的迴應。好比把用戶的微信跟他在咱們網站上的賬戶綁定到一起。
名詞
- Laravel:是一套 PHP 框架,你能夠用它建立 PHP 應用程序。
- MVC:是設計程序的一種方法,它會把程序按功能分紅幾個部分。M 表示 Model (模型),通常用它來表示程序裏面的數據。V 表示 View (視圖),展現層面的東西都放到 View 裏面。C 表示 Controller (控制器),它裏面包含的是處理不一樣請求的代碼。好比用戶請求訪問你的網站首頁,控制器接受到這個請求之後,從 Model 那裏調出數據,而後發送到 View 那裏,View 會包裝一下這些數據,把最終的結果顯示給用戶。
- Symfony:是一套 PHP 框架,Drupal 8 裏面會使用 Symfony 框架裏面的幾個組件,這篇文章裏提到的 Laravel 也用到了很多 Symfony 的組件。能夠確定的是 Symfony 是一款優秀的框架。
- Ruby on Rails:是一套用 Ruby 語言寫的框架,你可使用它快速的建立本身的應用程序。
- 應用:是指 Application ,意思就是應用程序。在這篇文章裏,你也能夠把 「應用」 當作是一個網站。