微信扫码关注公众号并登录网站

微信扫码关注公众号并登录网站

业务需求:

用户点击网站登陆,弹出二维码,用户打开微信扫描二维码登陆,如果用户没有关注,先关注微信公众号再登陆

技术:

  微信生成带参数临时二维码 

  文档: [https://developers.weixin.qq.com/doc/offiaccount/Account_Management/Generating_a_Parametric_QR_Code.html](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/Message_Management/Receiving_event_pushes.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']);
    }

你可能感兴趣的:(微信扫码关注公众号并登录网站)