背景
公司有一個產品,需要用到微信授權登錄及微信消息推送等功能。本來能夠簡單的使用公眾號的接口將appid和appsecrect等信息寫到配置文件里,但是作為一個產品化的東西,從體驗等各方面來講都不能那么的順暢。於是打算對接微信開放平台。本文是基於Laravel的一次微信開放平台整合記錄,如果能夠幫到一些朋友,自然是非常高興的事情。
平台賬號申請
網址是https://open.weixin.qq.com/ 進入后選擇第三方平台,點擊創建第三方平台按鈕。如下圖。
填完基礎的信息后。下一步,選擇必須的服務,此處省略圖,選擇你要用到的服務就行了。下圖是最后一步需要填寫的相關參數信息。登錄授權的發起頁域名為業務系統部署域名;授權測試公眾號列表是用於測試的公眾號的原始id,用分號隔開;授權事件接收URL是用於接收component_verify_ticket等公眾號授權信息的接口地址,此處先在laravel中寫了個接口地址/notification/openPlatform;公眾號消息校驗Token隨便填一個就可以了;解密Key填一個在代替公眾號收發消息過程中使用。必須是長度為43位的字符串,只能是字母和數字;消息與事件URL這個厲害了,所有公眾號的消息和事件到時候都會轉發到這個接口里來的,我這邊填/notification/openIndex/$APPID$,后面的$APPID$這個參數到時候會替換成對應公眾號的appid,這里只是個占位符,當然路由里必須得有這個參數。如果是沒有路由系統的一些框架,可能需要通過pathinfo的方式進行傳遞了,這里不允許使用?appid=1234這種方式進行傳遞;開發域名就是系統部署域名,一般小系統跟登錄授權域名保持一致,分布式的可能會有多個服務器或者站點來部署;ip地址白名單就不用多說了,就是服務器的ip地址,除了這個ip,其他的都無法訪問。
填完上述信息進行保存就OK了。到此整個申請開放平台的第一步過程就結束了。接下來我們就要取寫程序,進行測試,騰訊有一套自動化測試系統,通過自動化測試系統才能夠進行全網發布,下面要開始Coding了,會貼一些關鍵代碼。
Coding
編碼前先到應用的詳情中把AppId和AppSecret拿過來,找個地方先保存起來。
編碼這邊用到了一個第三方微信類庫,還是比較推薦使用的。叫EasyWechat,通過composer把它添加到項目中去。在config文件中先配置下appid和appsecret等信息。
'open_platform' => [ 'app_id' => 'wxc9c43170xxxx791', 'secret' => '6d36b19b6xxxxxxxxxf531be47f6235a', 'token' => 'kftcvr1436942017', 'aes_key' => 'ZQnZsLxxxxxxxxxwmmBSTofPzauHBhCIgsVgLGVwncNA' ],
先寫幾個路由。
Route::any('/notification/openPlatform','Service\OpenPlatformController@notify')->name('notification.openPlatformNotify'); //微信通知,主要是component_verify_ticket等信息 Route::any('/notification/openIndex/{appid}','Service\OpenPlatformController@index')->name('notification.openPlatformIndex'); //所有微信公眾號消息入口,包括文本、圖文、語音、地理位置等各種信息,這個具體實現就相當於做一個公眾號平台了。 Route::any('/wxcallback','Service\OpenPlatformController@wxcallback')->name('notification.openPlatformCallback'); //授權回調方法,用於保存appid和refresh_token Route::any('/wxauth','Service\OpenPlatformController@auth')->name('notification.openPlatformAuth'); //預授權頁面 Route::any('/wxtest','Service\OpenPlatformController@test')->name('notification.openPlatformTest'); //測試頁
編寫notify方法。SDK 內部已實現緩存 component_veirfy_ticket
,開發者無需另行處理該事件。使用 doctrine/cache 來完成緩存工作,它支持基本目前所有的緩存引擎。默認使用文件緩存,如果要用redis等其他緩存方式,比如多台服務器這種情況。請查閱easywechat官方文檔緩存那部分。
use App\Http\Controllers\Controller; use EasyWeChat\Core\Exception; use EasyWeChat\Foundation\Application; use EasyWeChat\OpenPlatform\Guard; use Illuminate\Support\Facades\DB; use Symfony\Component\HttpFoundation\Response; public function notify(){ $options = ['open_platform' => config('wechat.open_platform')]; $app = new Application($options); $openPlatform = $app->open_platform; $server = $openPlatform->server; $server->setMessageHandler(function($event) use($openPlatform){ switch ($event->InfoType) { case Guard::EVENT_AUTHORIZED: // 授權成功 $res = $openPlatform->getAuthorizationInfo($event->AuthorizationCode); //@TODO 此處需要檢查res是否正常 //Save to DB $appid = $res->authorization_info['authorizer_appid']; $refresh_token = $res->authorization_info['authorizer_refresh_token']; DB::table("wechat_platform")->where('app','hr')->update(['appid' => $appid,'refresh_token' => $refresh_token]); break; case Guard::EVENT_UPDATE_AUTHORIZED: // 更新授權 // break; case Guard::EVENT_UNAUTHORIZED: // 取消授權 // break; } }); $response = $server->serve(); return $response; }
編寫預授權頁面。這里前端要寫個頁面,在頁面中加上超鏈接,必須在同一個域名下。鏈接到auth方法。
<a style="color: inherit" href="http://hr.hackcat.com/wxauth"><p>微信平台綁定</p></a>
這邊會跳轉到微信的授權頁。彈出一個授權二維碼,公眾號賬號的主人掃一下授權一下會跳回到下面的回調頁面。
public function auth(){ $options = ['open_platform' => config('wechat.open_platform')]; $app = new Application($options); $openPlatform = $app->open_platform; $response = $openPlatform->pre_auth->redirect('http://hr.hackcat.com/wxcallback'); return $response; }
編寫授權回調頁面。這里主要是保存 authorizer_appid和authorizer_refresh_token信息,用於今后api的調用。
public function wxcallback(){ $options = ['open_platform' => config('wechat.open_platform')]; $app = new Application($options); $openPlatform = $app->open_platform; try{ $res = $openPlatform->getAuthorizationInfo($authorizationCode = null); $appid = $res->authorization_info['authorizer_appid']; $refresh_token = $res->authorization_info['authorizer_refresh_token']; DB::table("wechat_platform")->where('app','hr')->update(['appid' => $appid,'refresh_token' => $refresh_token]); return 'Success'; }catch (Exception $ex){ abort(404,$ex->getMessage()); } }
public function test(){ $options = ['open_platform' => config('wechat.open_platform')]; $app = new Application($options); $openPlatform = $app->open_platform; $authInfo = DB::table("wechat_platform")->where('app','hr')->first(); $app = $openPlatform->createAuthorizerApplication($authInfo->appid, $authInfo->refresh_token); $userService = $app->user; $user = $userService->get("oSQ2Ks_6ns0ahqKvzO_voIzbMdjI"); dd($user); }
上面的是測試方法,用於測試保存的appid和refresh_token是否工作。
這一篇就到此為止吧,期間mac的chrome奔潰了N次,重復寫了好幾遍,都快怒了。
PS: 這個系統由於用不到消息管理,所以去掉了權限的消息管理功能,全網發布的時候就不用寫消息管理的測試了。如果有朋友遇到了全網發布時候測試問題,歡迎留言。