微信掃碼關注公衆號並登陸網站

業務需求:
 
    用戶點擊網站登錄,彈出二維碼,用戶打開微信掃描二維碼登錄,若是用戶沒有關注,先關注微信公衆號再登錄 
 
技術:
 
      微信生成帶參數臨時二維碼 
      文檔: https://developers.weixin.qq.com/doc/offiaccount/Account_Management/Generating_a_Parametric_QR_Code.html
     
      微信事件推送(用戶掃碼就是一個掃碼事件)
      文檔:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_event_pushes.html
         
      微信公衆號獲取用戶信息
      文檔:https://developers.weixin.qq.com/doc/offiaccount/User_Management/Get_users_basic_information_UnionID.html#UinonId
     推送事件裏的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']);
    }

 

問題:
    按照文檔說的, 若是用戶還未關注公衆號,則用戶能夠關注公衆號,關注後微信會將帶場景值關注事件推送給開發者。可是我這邊若是沒關注,點了關注以後登陸邏輯就不會走,因此在訂閱事件裏面也把掃碼登錄的邏輯加上了
相關文章
相關標籤/搜索