这个方法最开始用在尚未“微信开放平台”的时候,如今也有很多网站在用,简单说就是生成一个临时二维码放到服务器,而后微信扫描二维码后将该值传递给服务器进行比对,实现登录,和手机动态码登录思路相似。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