zoukankan      html  css  js  c++  java
  • 微信扫码关注公众号并登录网站

    业务需求:
     
       用户点击网站登陆,弹出二维码,用户打开微信扫描二维码登陆,如果用户没有关注,先关注微信公众号再登陆 
     
    技术:
     
          微信生成带参数临时二维码 
         
          微信事件推送(用户扫码就是一个扫码事件)
             
          微信公众号获取用户信息
         推送事件里的FromUserName 就是用户的openid
     
    设计实现:
            1.用户点击网站微信登陆,微信请求后端接口,后端生成一个带随机场景值的二维码(这里我用的rand(1000000,9999999)生成随机sence_id),将二维码链接和sence_id一起返回前端
    $sence_id = rand(1000000,9999999);//100W到999W之间的数字为网站登陆场景 todo:随机值重复情况没有做处理
    $wxConfig = new WxConfig();
    $img = $wxConfig->getQrCode(60,'temp',$sence_id,true);
    $redis = Cache::store('redis')->handler();
    $redis->setex('77dj_wx:user:'.$sence_id,120,0);//已sence_id为键
    return wx_successReturn(['img'=>$img,'sence_id' => $sence_id]);
       
       2.网站展示二维码并一直轮询后台获取用户信息,参数为sence_id,根据返回的信息判断用户是否扫码登陆
    $redis = Cache::store('redis')->handler();
    $key = '77dj_wx:user:'.$data['sence_id'];//todo:key前缀加到配置里面
    $exists = $redis->exists($key);
    if(!$exists) return wx_errorReturn(null,-1,'二维码已过期');
    $user_id = $redis->get($key);
    if($user_id) {
        $user_info = Db::name('user')->find($user_id);
        $redis->del('77dj_wx:user:'.$data['sence_id']);
        return wx_successReturn(['user_info'=>$user_info]);
    } else {
        return wx_successReturn(['user_info'=>null]);
    }
       
       3.用户扫码,如果用户没有没有关注公众号,会先关注,然后再执行登陆逻辑,如果关注过,会直接进入登陆逻辑
        /**
         * 推送的事件处理
         */
        private function doEvent($postObj) {
            switch ($postObj->Event) {
                case 'subscribe' :
                    $this->doSubscribe($postObj);
                    break;//关注事件
                case 'unsubscribe' :
                    $this->unSubscribe($postObj);
                    break; //取消关注
                case 'CLICK' :
                    //TODO... 菜单按钮需要重做
    //                $this->menuClick($postObj);
                    break;//菜单点击事件
                case 'SCAN' :
                    $this->dealScan($postObj);
                    break;//扫码事件
            }
        }
    
        /**
         * 订阅关注
         */
        private function doSubscribe($postObj) {
            $eventKey = $postObj->EventKey;
            $sence_id = explode('_', $eventKey)[1];
            if ($sence_id > 1000000) {//用户登陆
                $postObj->EventKey = $sence_id;
                $this->createUser($postObj);
            }
        }
    
        /**
         * 扫码事件
         */
        private function dealScan($postObj) {
            if ($postObj->EventKey > 1000000) {//用户登陆
                $this->createUser($postObj);
            }
        }
    
        /**
         *
         */
        private function createUser($postObj) {
            $user = new User();
            $access_token = $this->getToken();
            $userArr = $user->createUser('','','dj_pc','PC',$postObj->FromUserName,$access_token);
            if(isset($userArr['app_session'])) {
                $session = $userArr['app_session'];
                //用户信息
                $userInfo = getAppUserInfo($session, true);
            }
    
            $redis = Cache::store('redis')->handler();
            $prefix = config('const.redis_prefix');
            $key = $prefix['user_token'];
            $redis->hset($key,$userArr['c_session'],$userArr['id']);
            $redis->setex('77dj_wx:user:'.$postObj->EventKey,3600,$userArr['id']);
        }
    问题:
        按照文档说的, 如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事件推送给开发者。但是我这边如果没关注,点了关注之后登录逻辑就不会走,所以在订阅事件里面也把扫码登陆的逻辑加上了
  • 相关阅读:
    LINUX和git
    drf [Django REST Framework]
    python用法小技巧
    爬虫
    django入门到精通
    前端框架
    mysql数据库
    网络编程和并发编程
    面向对象
    python基础
  • 原文地址:https://www.cnblogs.com/jint-php7/p/11936963.html
Copyright © 2011-2022 走看看