PHP微信扫描登陆(模拟微信企业号平台登陆)

最近在做一款基于微信公众号的管理系统,我们为公司的微信公众号提供后台管理功能,此系统能够实现关注人信息的上传和下载,能实现信息的推送,以及实现一些公司业务相关的功能。鉴于此系统紧密的微信公众号结合,而且能够给关注公众号的人推送信息,于是在系统的安全上就有别于其他的系统,同时系统也需要用户的微信信息,于是我们决定使用类似于微信企业号的登陆机制(微信企业号)。

准备工作:在决定使用这套登陆机制以后,我们开始根据微信公众号提供的文档进行开发,微信扫描二维码登陆的业务逻辑可简单归结如下:用户扫描二维码——后台验证此微信用户是否存在——跳转输入密码——验证密码进行登陆。看似简单的几个业务逻辑,实则在开发中遇到不少问题。在进行正式的开发前,我们需要确定以下几个必要的工作:

1. 我们的微信公众号是否获得高级权限,微信扫描登陆需要(OAuth2.0网页授权权限)。高级权限的获得,需要进行微信认证,提供公司相关资料,缴纳一定费用。

设置—微信认证

PHP微信扫描登陆(模拟微信企业号平台登陆)_第1张图片

2.在获得OAuth2.0网页授权权限以后我们查阅微信公众号提供的文档(OAuth2.0网页授权)我们需要对此权限进行相关配置,首先我们需要配置授权回调域名

开发者中心——接口权限表(网页服务)


3.配置好OAuth2.0网页授权权限,我们需要了解一个微信公众号的第三方平台——微信开放平台,在我们的业务中,我们需要使用微信号作为我们网站登陆、移动端登陆的账号,因此我们选择了微信开放平台,来进行我们账号的统一,此处我们需要介绍一下微信开放平台:

微信开发平台主要用于将微信服务号、网站应用、移动应用统一起来,在微信开放平台进行注册绑定相关应用审核以后我们可以获得一个UnionID,我们可以通过这个id在不同应用中唯一标识我们的用户。同时我们的微信登陆的功能还需要使用微信开放平台提供的接口:


同时微信开放平台下提供了更多的高级接口,需要在第三方平台处申请。

在这个地方笔者出现了几个问题并再多次阅读文档后得到解决:


(1)通过开放平台下的文档,配置wxLogin的时候,对于scope参数,只能填写snsapi_login,填写其他的比如 (微 信公众平台文档中的snsapi_base、snsapi_userinfo)会出现报错。解决方案:在开放平台中,拥有另外一 种机 制来获取高级权限的access_token,换句话说此处填写snsapi_login即可,而反复测试下,通过此二维码跳 转的 code换取的access_token无法请求高级接口,我们应该在管理中心——公众号第三方平台配置申请权限, 则可 以使用access_token去请求高级接口。

(2)在配置wxLogin的时候,根据文档我们配置的appid、secret均为微信开放平台下申请网站应用的appid,而 appid在微信公众号下也是可用的,所以我们可以通过此appid和拥有权限的access_token去请求高级接 口,获得 用户信息。


注意:微信开放平台需要缴纳相关费用进行材料审核,如果有需求完成微信扫描登陆、不同应用间的账号统一,那么这个费用是必须的。

在完成好以上三个步骤以后我们就可以正式进行微信扫描登陆的业务开发了。


页面开发:可以根据微信开放平台提供的js,就可以获得登陆时扫描的二维码。代码示例:

 
 
这里的id即为你需要放置二维码的div的id,state参数则是配合你自己网站的安全机制,还有一个href参数,来调整二维码的样式。


用户扫描二维码,同意授权登陆以后,网站会自动跳转至你填写的回调URL,此URL可以是你后台的控制器当中,根据接收的code参数,后台模拟https请求,获得用户的union_id,进行用户验证,如果用户存在,则跳转至密码输入页面,如果不存在,则跳转至失败页面。代码示例:

    public function admin_login() {
        //如果存在session直接访问登陆界面
        if(!empty($this->session->userdata('weixin_name'))){
            if($this->session->userdata('weixin_name') != "not_exist"){
                $weixin_name = $this->session->userdata('weixin_name');
                $time = substr($weixin_name,strlen($weixin_name)-strlen(date("Y-m-d H:i:s")),strlen(date("Y-m-d H:i:s")));
                if(time()-strtotime($time)<5*60){
                    $data['login_frame'] = "login_first_suc";
                    $this->load->view("login",$data);
                }else{
                    $this->session->unset_userdata('weixin_name');
                    $login_url = URL;
                    header("Location:".$login_url);
                }
            }else{
                $data['login_frame'] = "login_error";
                $this->load->view("login",$data);
            }
        }else{
            $state_str = $this->input->get("state");
            if($state_str){
                if($state_str == md5($this->config->item('kaifang')['state'])){
                    $code = $this->input->get("code");
                    $user_access = $this->wei_model->get_access_token_from_web($code);
                    if($user_access){
                        if($username = $this->login_model->check_weixin_user($user_access)){
                            $this -> session -> set_userdata("weixin_name",$user_access->unionid.date("Y-m-d H:i:s"));
                        }else{
                            $this -> session -> set_userdata("weixin_name","not_exist");
                        }
                    }else{
                        $this -> session -> set_userdata("weixin_name","not_exist");
                    }
                }else{
                    //非法登陆
                    $this -> session -> set_userdata("weixin_name","not_exist");
                }
                $login_url = URL;
                header("Location:".$login_url);
            }else{
                $data['login_frame'] = "login_weixin";
                $this->load->view("login",$data);
            }
        }
    }
其中,我将weixin_name进行了session处理,同时对state参数进行了简单的md5加密验证。

到此为止,微信扫描二维码登陆的业务逻辑就算完成了,博主用了几天的时间才把文档读透,实现了相关的业务逻辑和权限控制。如果大家还有什么不明白的地方,可以留言交流。




你可能感兴趣的:(php微信开发)