>  기사  >  백엔드 개발  >  PHP WeChat PC QR 코드 로그인 구현 방법

PHP WeChat PC QR 코드 로그인 구현 방법

零下一度
零下一度원래의
2017-07-16 16:41:091696검색

이 글은 주로 PHP WeChat PC QR 코드 로그인의 구현 아이디어를 소개합니다. 관심 있는 친구들이 참고할 수 있습니다.

1. 아이디어:

아이디어의 핵심은 다음과 같습니다. WeChat 클라이언트 상호 작용 측면에서 보면 현재 WeChat 로그인은 WeChat을 통해서만 가능합니다.

하지만 WeChat에는 맞춤형 QR 코드를 생성하는 특별한 방법이 있습니다. 이를 통해 QR 코드를 PC에 표시할 수 있고, QR 코드의 값은 우리가 정의할 수 있습니다. 또한 WeChat 개발 문서에는 WeChat을 사용하는 사용자를 감지하여 QR 코드를 스캔하고 값을 얻을 수 있는 스캔 이벤트가 있습니다. 사실 문제의 핵심은 바로 이 값에 있다. 이 값은 차이나유니콤 PC와 위챗 간의 통신 ID로 간주된다.

2. 구체적인 구현 과정 (아래 코드는 TP5 프레임워크를 사용하며, 서비스 계정의 공개 계정이 있다는 것이 주요 전제입니다.)

1. PC 측에서 QR 코드를 생성합니다.

코드는 다음과 같습니다:


Controller:

namespace app\home\controller;

class Recognition extends Base{

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

model:

namespace app\common\model;

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

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

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

    import('Net.Http');
    $http = new \Http();

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

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

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

성공한 후 다음을 반환하는 것을 볼 수 있습니다.

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

실제로 값을 나타내는 id 값이 있습니다. QR코드!


그럼 티켓은 QR코드 링크입니다. 즉, 스캔 이벤트에서 이 QR코드를 스캔하여 얻은 값이 바로 이 id입니다.

아래 WeChat 처리를 확인하세요

1. QR 코드를 스캔한 후:


namespace app\mobile\controller;

class Wechat extends Base{

  public function index()
  {
    import('Wechat.Wechat');
    $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['MsgType'] == 'event') {
      $id = $data['EventKey'];
      switch (strtoupper($data['Event'])) {
        case 'SCAN':
          return $this->scan($id, $data['FromUserName']);
        case 'CLICK':
          //回复?
          return array('click', 'text');
          break;
        case 'SUBSCRIBE':
          //关注
          return array('Welcome', 'text');
          break;
        case 'UNSUBSCRIBE':
          //取关

          return array('BYE-BYE', 'text');
        case 'LOCATION':
          //定位

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

      if ($data['MsgType'] == 'location') {

      }

      if (import('@.ORG.' . $data['MsgType'] . 'MessageReply')) {

      }
    }

    return false;
  }
  private function scan($id, $openid = '', $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;);
    }
  }
}

위의 스캔 방법에는 다음과 같은 판단이 있음을 알 수 있습니다:

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

$id는 해당 QR코드의 값으로 앞서 생성한 id입니다. (사실 Scan에서 다양한 이벤트를 구분하기 위해 id가 있는 login_qrcode 테이블을 의도적으로 증가시킵니다. 1000000000부터 시작하는 ID로 위치).

그런 다음 if 뒤의 처리를 살펴보세요.


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;);
       }

조건이 충족되고 openid를 가진 사용자가 있는 경우

updatelogin_qrcode 테이블을 실행하고 uid를 사용자 ID로 변경합니다. (핵심은 왜 사용자가 로그인을 했는데도 해당 ID에 해당하는 데이터의 uid가 사용자 ID로 업데이트되는지입니다.)

3. 1에서 QR 코드를 얻은 후 계속해서 PC 세그먼트가 요청을 중단하지 않고 대신 방법을 학습했습니다.


* 微信登录异步请求
   * @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);
      }
  }

위의 방법으로 qrcode_id를 얻은 것을 볼 수 있습니다. , 즉 1 에서 반환된 ID이고, 반환된 다른 ID는 QR 코드입니다.

회전 훈련 과정은 이 ID를 사용하여 login_qrcode 테이블의
status를 지속적으로 확인하는 것입니다. uid가 존재하면 로그인이 성공한 것입니다! uid를 사용하여 자동으로 로그인할 수 있습니다.

4. 위

의 핵심은 중간 테이블 login_qrcode가 QR 코드를 생성하고 동시에 WeChat 측에 사용자 UID를 삽입하는 데 사용된다는 것입니다. 로그인을 달성하기 위해 PC 측에서 감지되었습니다.

위 내용은 PHP WeChat PC QR 코드 로그인 구현 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.