Maison  >  Article  >  développement back-end  >  PHP implémente la connexion par code QR WeChat PC

PHP implémente la connexion par code QR WeChat PC

巴扎黑
巴扎黑original
2017-08-14 11:11:405190parcourir

Cet article présente principalement les idées de mise en œuvre de la connexion par code QR PHP WeChat PC, qui a une certaine valeur de référence. Les amis intéressés peuvent s'y référer

1. Idées :

<.>La clé de l'idée est de savoir comment interagir avec WeChat. Après tout, actuellement, la connexion à WeChat ne peut se faire que via WeChat.


Mais WeChat dispose d'une méthode spéciale pour générer des codes QR personnalisés, qui nous permet d'afficher le code QR sur le PC, et la valeur du code QR peut être celle que nous définissons. De plus, il existe un événement d'analyse dans la documentation de développement WeChat, qui peut détecter l'utilisateur utilisant WeChat pour scanner le code QR et obtenir la valeur. En fait, la clé du problème réside dans cette valeur. Cette valeur est considérée comme un identifiant de communication entre China Unicom PC et WeChat.

2. Processus de mise en œuvre spécifique (Le code ci-dessous utilise le framework TP5, et une prémisse majeure est qu'il existe un compte public du compte de service)

1. Générez le QR code sur PC :

Le code est le suivant :


Contrôleur :


namespace app\home\controller;

class Recognition extends Base{

  public function seeLoginQrcode(){
    $qrcode_return = model(&#39;Recognition&#39;)->getLoginQrcode();
    if($qrcode_return[&#39;error_code&#39;]){
      return $this->returnJson("获取失败!",0);
    }else{
      $data=array(
          &#39;url&#39;=>$qrcode_return[&#39;ticket&#39;],
          &#39;qrcode_id&#39;=>$qrcode_return[&#39;id&#39;],
      );
      return $this->returnJson("获取成功!",1,$data);
    }
  }
}
modèle :


namespace app\common\model;

use think\Model;
class Recognition extends Model{
  protected $autoWriteTimestamp = false;
  //生成登录用的临时二维码
  public function getLoginQrcode(){
    $appid   = config(&#39;THINK_SDK_WEIXIN.APP_KEY&#39;);
    $appsecret = config(&#39;THINK_SDK_WEIXIN.APP_SECRET&#39;);
    if(empty($appid) || empty($appsecret)){
      return(array(&#39;error_code&#39;=>true,&#39;msg&#39;=>&#39;请联系管理员配置【AppId】【 AppSecret】&#39;));
    }

    $database_login_qrcode = model(&#39;LoginQrcode&#39;);
    $database_login_qrcode->where(array(&#39;add_time&#39;=>array(&#39;lt&#39;,($_SERVER[&#39;REQUEST_TIME&#39;]-604800))))->delete();

    $data_login_qrcode[&#39;add_time&#39;] = $_SERVER[&#39;REQUEST_TIME&#39;];
    $database_login_qrcode->save($data_login_qrcode);
    $qrcode_id = $database_login_qrcode->getLastInsID();
    if(empty($qrcode_id)){
      return(array(&#39;error_code&#39;=>true,&#39;msg&#39;=>&#39;获取二维码错误!无法写入数据到数据库。请重试。&#39;));
    }

    import(&#39;Net.Http&#39;);
    $http = new \Http();

    //微信授权获得access_token
    $access_token_array = model(&#39;AccessTokenExpires&#39;)->getAccessToken();
    if ($access_token_array[&#39;errcode&#39;]) {
      return(array(&#39;error_code&#39;=>true,&#39;msg&#39;=>&#39;获取access_token发生错误:错误代码&#39; . $access_token_array[&#39;errcode&#39;] .&#39;,微信返回错误信息:&#39; . $access_token_array[&#39;errmsg&#39;]));
    }
    $access_token = $access_token_array[&#39;access_token&#39;];

    $qrcode_url=&#39;https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=&#39;.$access_token;
    $post_data[&#39;expire_seconds&#39;] = 604800;
    $post_data[&#39;action_name&#39;] = &#39;QR_SCENE&#39;;
    $post_data[&#39;action_info&#39;][&#39;scene&#39;][&#39;scene_id&#39;] = $qrcode_id;

    $json = $http->curlPost($qrcode_url,json_encode($post_data));
    if (!$json[&#39;errcode&#39;]){
      $condition_login_qrcode[&#39;id&#39;]=$qrcode_id;
      $data_login_qrcode[&#39;id&#39;] = $qrcode_id;
      $data_login_qrcode[&#39;ticket&#39;] = $json[&#39;ticket&#39;];
      if($database_login_qrcode->isUpdate(true)->save($data_login_qrcode)){
        return(array(&#39;error_code&#39;=>false,&#39;id&#39;=>$qrcode_id,&#39;ticket&#39;=>&#39;https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=&#39;.urlencode($json[&#39;ticket&#39;])));
      }else{
        $database_login_qrcode->where($condition_login_qrcode)->delete();
        return(array(&#39;error_code&#39;=>true,&#39;msg&#39;=>&#39;获取二维码错误!保存二维码失败。请重试。&#39;));
      }
    }else{
      $condition_login_qrcode[&#39;id&#39;] = $qrcode_id;
      $database_login_qrcode->where($condition_login_qrcode)->delete();
      return(array(&#39;error_code&#39;=>true,&#39;msg&#39;=>&#39;发生错误:错误代码 &#39;.$json[&#39;errcode&#39;].&#39;,微信返回错误信息:&#39;.$json[&#39;errmsg&#39;]));
    }
  }
}
Vous pouvez voir qu'il revient après le succès :

Copier le code Le code est le suivant :

return(array('error_code'=>false,'id'=>$qrcode_id,'ticket'=>'https://mp.weixin .qq.com/cgi-bin/showqrcode ?ticket='.urlencode($json['ticket'])));

Il existe une valeur d'identifiant, qui représente en fait la valeur du code QR !


Ensuite, le ticket est le lien vers le code QR. C'est-à-dire que la valeur obtenue en scannant ce code QR lors de l'événement scan est cet identifiant.

Vérifiez le traitement WeChat ci-dessous

1. Après avoir scanné le code QR :


namespace app\mobile\controller;

class Wechat extends Base{

  public function index()
  {
    import(&#39;Wechat.Wechat&#39;);
    $wechat = new \Wechat();
    $data = $wechat->request();
    list($content, $type) = $this->reply($data);
    if ($content) {
      $wechat->response($content, $type);
    }
    else {
      exit();
    }
  }
  public function reply($data)
  {
    if ($data[&#39;MsgType&#39;] == &#39;event&#39;) {
      $id = $data[&#39;EventKey&#39;];
      switch (strtoupper($data[&#39;Event&#39;])) {
        case &#39;SCAN&#39;:
          return $this->scan($id, $data[&#39;FromUserName&#39;]);
        case &#39;CLICK&#39;:
          //回复?
          return array(&#39;click&#39;, &#39;text&#39;);
          break;
        case &#39;SUBSCRIBE&#39;:
          //关注
          return array(&#39;Welcome&#39;, &#39;text&#39;);
          break;
        case &#39;UNSUBSCRIBE&#39;:
          //取关

          return array(&#39;BYE-BYE&#39;, &#39;text&#39;);
        case &#39;LOCATION&#39;:
          //定位

          break;
      }
    }
    else {
      if ($data[&#39;MsgType&#39;] == &#39;text&#39;) {
        return array("测试成功!",&#39;text&#39;);
      }

      if ($data[&#39;MsgType&#39;] == &#39;location&#39;) {

      }

      if (import(&#39;@.ORG.&#39; . $data[&#39;MsgType&#39;] . &#39;MessageReply&#39;)) {

      }
    }

    return false;
  }
  private function scan($id, $openid = &#39;&#39;, $issubscribe = 0)
  {
    if ((1000000000 < $id) && $openid) {
       if ($user = model(&#39;Member&#39;)->field(&#39;id&#39;)->where(array(&#39;third_id&#39; => $openid))->find()) {
         $data=array(
           &#39;id&#39;=>$id,
           &#39;uid&#39;=> $user[&#39;id&#39;]
         );
         model(&#39;LoginQrcode&#39;)->isUpdate()->save($data);
         return array(&#39;登陆成功&#39;, &#39;text&#39;);
       }
       $data=array(
         &#39;id&#39;=>$id,
         &#39;uid&#39;=>-1
       );
       model(&#39;LoginQrcode&#39;)->isUpdate(true)->save($data);
      $return[] = array(&#39;点击授权登录&#39;, &#39;&#39;,config(&#39;SITE_LOGO&#39;), config(&#39;SITE_URL&#39;) . &#39;/mobile/WechatBind/ajaxWebLogin?qrcode_id=&#39; . $id);
      return array($return, &#39;news&#39;);
    }
  }
}
La méthode de numérisation ci-dessus a ce jugement. , vous pouvez voir :

if ((1000000000 < $id) && $openid) {

Le $id est la valeur du code QR correspondant, qui est le id que nous avons généré auparavant (en fait, afin de distinguer les différents événements dans Scan, nous avons délibérément incrémenté la table login_qrcode où se trouve l'id à partir de 1000000000).

Ensuite, regardez le traitement derrière si :


if ($user = model(&#39;Member&#39;)->field(&#39;id&#39;)->where(array(&#39;third_id&#39; => $openid))->find()) {
         $data=array(
           &#39;id&#39;=>$id,
           &#39;uid&#39;=> $user[&#39;id&#39;]
         );
         model(&#39;LoginQrcode&#39;)->isUpdate()->save($data);
         return array(&#39;登陆成功&#39;, &#39;text&#39;);
       }
Si les conditions sont remplies et qu'il y a un utilisateur avec l'openid, mettez à jour la table login_qrcode et modifiez le uid à l'identifiant de l'utilisateur. (Voici la clé, pourquoi l'uid des données correspondant à l'identifiant est-il mis à jour avec l'identifiant de l'utilisateur même si l'utilisateur est connecté).

3. Continuez à regarder du côté PC. Le segment PC n'a pas arrêté de demander après avoir obtenu le code QR en 1, mais a plutôt formé une méthode :


* 微信登录异步请求
   * @return \think\response\Json
   * created by sunnier<xiaoyao_xiao@126.com>
   */
  public function ajaxWechatLogin(){
      for ($i = 0; $i < 6; $i++) {
        $database_login_qrcode = model(&#39;LoginQrcode&#39;);
        $condition_login_qrcode[&#39;id&#39;] = input(&#39;get.qrcode_id&#39;);
        if(empty($condition_login_qrcode[&#39;id&#39;])){
          return $this->returnJson(&#39;未获取到qrcode_id!&#39;,0);
        }
        $now_qrcode = $database_login_qrcode->field(&#39;`uid`&#39;)->where($condition_login_qrcode)->find();
        if (!empty($now_qrcode[&#39;uid&#39;])) {
          if ($now_qrcode[&#39;uid&#39;] == -1) {
            $data_login_qrcode[&#39;uid&#39;] = 0;
            $database_login_qrcode->where($condition_login_qrcode)->isUpdate(true)->save($data_login_qrcode);
            return $this->returnJson(&#39;请在微信公众号点击授权登录!&#39;,0);
          }
          $database_login_qrcode->where($condition_login_qrcode)->delete();
          $result = model(&#39;Member&#39;)->autologin(&#39;id&#39;, $now_qrcode[&#39;uid&#39;]);
          if (empty($result[&#39;error_code&#39;])) {
            return $this->returnJson(&#39;登录成功!&#39;,1,$result[&#39;user&#39;]);
          } else if ($result[&#39;error_code&#39;] == 1001) {
            return $this->returnJson(&#39;没有查找到用户,请重新扫描二维码!&#39;,0);
          } else if ($result[&#39;error_code&#39;]) {
            return $this->returnJson(&#39;登陆失败!&#39;,0);
          }
        }
        if ($i == 5) {
          return $this->returnJson(&#39;登陆失败&#39;,0);
        }
        sleep(3);
      }
  }
Vous pouvez voir que la méthode ci-dessus obtient le qrcode_id, qui est l'identifiant renvoyé en 1, et l'autre retour est le code QR.

Le processus de formation en rotation consiste à utiliser cet identifiant pour vérifier en permanence l'état de la table login_qrcode. Si l'uid existe, cela prouve que la connexion est réussie ! Vous pouvez utiliser l'uid pour vous connecter automatiquement.

4. La clé de ce qui précède

est que la table intermédiaire login_qrcode sert de pont pour générer des codes QR et insérer l'ID utilisateur du côté WeChat. , le côté PC détecte la table. Le changement d'état permet la connexion.

3. Dépôt de code

https://git.oschina.net/kebenxiaoming/erwmlogin1

Clonez-le directement si vous en avez. des questions, soulever un problème ou m'envoyer un message privé

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn