這個方法最開始用在尚未「微信開放平臺」的時候,如今也有很多網站在用,簡單說就是生成一個臨時二維碼放到服務器,而後微信掃描二維碼後將該值傳遞給服務器進行比對,實現登錄,和手機動態碼登錄思路相似。php
先把咱們要實現的步驟說下:html
用戶訪問微信登錄頁面,程序生成一個臨時二維碼。web
用戶使用微信掃描剛生成的二維碼。瀏覽器
掃碼後微信發送二維碼所含內容給網站程序。服務器
客戶端每隔N秒(或填寫)將第一步的二維碼內容和網站從微信接收的二維碼內容比對,若是找到則登錄成功。微信
因臨時二維碼生成和掃碼操做須要用到公衆帳號通信接口,所以咱們先配置它(微信相關頁面)。首先在@app/controllers/下新建一個名爲WxController.php的控制器文件而且定義一個actionIndex來處理和微信之間的交互,以下面代碼:yii2
namespace app\controllers; use Yii; use yii\web\Controller; use EasyWeChat\Foundation\Application;// 引入EasyWeChat class WxController extends Controller { /** * 服務器與微信通信處理接口 * @author abei<abei@nai8.me> */ public function actionIndex(){ /* * 'WECHAT'=>[ * 'appId'=>'xxx', * 'appSecret'=>'xxxxx', * 'token'=>'nai8_me' * ] */ $options = Yii::$app->params['WECHAT']; $app = new Application($options); $response = $app->server->serve(); $response->send(); } }
根據微信文檔,首先咱們須要經過服務器驗證。app
$response = $app->server->serve(); $response->send();
這段代碼就是處理和微信響應的,咱們在測試平臺填寫action的url和tokenyii
當配置驗證經過後,咱們再對微信服務器發過來的各類請求作相應處理,好比傳過來一個文本,好比一次二維碼掃描,好比一個地理位置,好比等等。關於EasyWechat對於和微信服務器交互的文檔能夠查看以下地址。函數
接下來咱們來處理微信發過來的請求,在本文檔裏咱們要處理的是掃描二維碼後的接收事件,固然掃描二維碼根據當前微信是否關注公衆號返回的是不一樣的,因篇幅問題,咱們只說關注後的狀況。
增長功能後的代碼以下
namespace app\controllers; use Yii; use yii\web\Controller; use EasyWeChat\Foundation\Application;// 引入EasyWeChat class WxController extends Controller { public $wxApp; /** * 服務器與微信通信處理接口 * @author abei<abei@nai8.me> */ public function actionIndex(){ $options = Yii::$app->params['WECHAT']; $app = new Application($options); $server = $app->server; $this->wxApp = $app; $server->setMessageHandler(function ($message) { switch ($message->MsgType) { case 'event':// SCAN & subscribe return $this->doEvent($message); break; } }); $response = $server->serve(); $response->send(); } /** * 處理事件 * @param $message * @author abei<abei@nai8.me> */ protected function doEvent($message){ switch ($message->Event) { case 'SCAN': return $this->doScan($message); break; } } /** * 處理具體掃描事件 * @param $message * @author abei<abei@nai8.me> */ protected function doScan($message){ $key = $message->EventKey; $openId = $message->FromUserName; return $openId; } }
爲防止函數過長,咱們拆分爲幾個小方法處理,同時增長一個叫作$wxApp的變量表明本次交互,串聯每一個函數。
咱們準備工做暫時到這裏,下面用到的時候再說。
如今咱們經過 EasyWeChat 來生成一個臨時二維碼,那就定義一個叫作 actionQrcode 的函數吧。
namespace app\controllers; use Yii; use yii\web\Controller; use EasyWeChat\Foundation\Application;// 引入EasyWeChat class WxController extends Controller { public $wxApp; ... public $enableCsrfValidation = false; /** * 生成一個臨時二維碼 * @author abei<abei@nai8.me> */ public function actionQrcode(){ $options = Yii::$app->params['WECHAT']; $app = new Application($options); $qrcode = $app->qrcode; $rand = mt_rand(100000,999999); $result = $qrcode->temporary($rand, 6 * 24 * 3600); $ticket = $result->ticket;// 或者 $result['ticket'] $url = $qrcode->url($ticket); return $this->render('qrcode',[ 'url'=>$url, 'rand'=>$rand ]); } }
actionQrcode 方法將一個隨機的6位數字放到了臨時二維碼中,這裏要說明有兩點
$url 即爲二維碼圖片地址,在視圖裏直接用img 標籤接收便可。
除了微信服務器驗證爲GET請求,其餘的事件均爲POST請求,可是yii2默認對於POST提交是進行crsf驗證的,所以爲了有效的接收微信服務器給咱們的推送信息,咱們須要關閉crsf驗證。
public $enableCsrfValidation = false; // 我就是用來關閉crsf驗證滴
這樣咱們就生成了一個含有$rand值的二維碼,對於如何使用完成登錄方法不少,我這裏使用瀏覽器請求方式,在actionQrcode的視圖內,我填寫以下代碼
<img src="<?= $url;?>" alt=""> <script> //todo 每隔N秒鐘向程序發起一次請求,詢問一個叫作wx_qrcode的數據表是否有含有$rand的記錄,若是有則php完成登錄,瀏覽器跳轉到好比我的中心等頁面 </script>
那麼接下來就是這個叫作wx_qrcode的表如何設計以及記錄如何產生的問題了。
若是你看了微信文檔必定知道,當咱們使用微信掃描臨時二維碼的時候,微信除了告訴咱們服務器二維碼所表明的$rand隨機數字外,還有一個叫作$openId的標識,它表明掃碼微信的惟一身份,所以咱們設計了wx_qrcode表,裏面含有open_id和rand。
思路是這樣的
掃碼後程序接到微信傳遞過來的open_id和rand隨機碼,進行會員初始化工做,同時往wx_qrcode表內存此記錄。
程序接到瀏覽器請求,根據請求中的rand隨機碼來查詢wx_qrcode,若是找到記錄,則找到了open_id,也就找到了此會員,而後使用Yii::$app->user->login()方法進行登陸受權,而後刪除該記錄後返給瀏覽器登陸成功,不然返回失敗,繼續讓瀏覽器N秒後詢問。
也就是說咱們須要修改第一步裏的微信掃碼處理程序,作簡單處理。
namespace app\controllers; use Yii; use yii\web\Controller; use EasyWeChat\Foundation\Application;// 引入EasyWeChat class WxController extends Controller { public $wxApp; public $enableCsrfValidation = false; ... /** * 處理具體掃描事件 * @param $message * @author abei<abei@nai8.me> */ protected function doScan($message){ $key = $message->EventKey; $openId = $message->FromUserName; $user = User::find()->where(['open_id'=>$openId])->one(); if($user == false){ //todo 新建會員 } $wxQrcode = new WxQrcode(); $wxQrcode->open_id = $openId; $wxQrcode->rand = $key; $wxQrcode->save(); } }
這只是一個思路,各位兄弟根據本身系統的狀況須要更加完善這塊的邏輯,反正這個掃描的接收,咱們須要填充wx_qrcode記錄,讓瀏覽器來詢問。
ok,接下來我再說下PHP如何處理瀏覽器諮詢的邏輯
public function actionAsk(){ $rand = Yii::$app->request->get('key'); $check = WxQrcode::find()->where(['rand'=>$rand])->one(); if($check){ $user = User::find()->where(['open_id'=>$check->open_id)->one(); Yii::$app->user->login($user); $check->delete(); return Json::encode(['done'=>true]); }else{ //todo 不作什麼,讓瀏覽器繼續問。 } }
掃碼登錄有不少,好比生成二維碼後不進行視圖的循環,而是掃碼後以動態碼形式用模板消息等發給微信,微信在頁面添加動態碼實現驗證登錄,就像兄弟連的微信登錄同樣。
方法不少,核心就一條,就是利用二維碼的內容進行PC和微信之間的傳遞。
更多yii文章歡迎來個人博客 http://nai8.me