微信第三方登录

微信第三方登录

96 
勃起狂奔者 
2017.09.19 20:54* 字数 1193 阅读 1075评论 0

前言:

当公司让我做微信的第三方登录时,我就想这个简单啊,下个sdk,调用几个方法就齐活了。结果当我打开微信第三方登录的文档时

 
image.png

简单的页两文档,比起微信支付不知道差到哪里去了,点开资源下载,也没有封装好的php SDK。所有的事情只有我们自己来了。

 
image.png

目录:

  1. 前期准备
  2. 开始登录
  3. 业务逻辑介绍
一.前期准备
  1. 我们需要申请,一个网站应用,这个都是大同小异,我就不赘述了。当然了还有交300块保护费用,这个也是跑不掉的。
  2. 获取到app_id和secret,还要设置好回调地址,将数据放到配置当中,我这里使用的tp3.2.3 ,使用其他框架的朋友也无所谓都是一样的
 
第三方登录配置
  1. 拼接出请求code的链接
    将下图中框起来的部分替换为我们配置好的数据,最后STATE是个用于安全的令牌可以不要。


     
    请求code

注意第三个参数scope,权限范围,我们后续肯定要获取用户信息的,所以我推荐使用snsapi_userinfo

我的选择是将这个拼接好了url直接用于我们站点的微信登录按钮上,这样我们就省去了再重定向的步骤

 
image.png

具体实现我是写了一个公共函数来拼接url,然后再视图页面直接调用这个函数。方法有很多,大家可以自己使用自己的方法。

当我们配置好了之后,我们就可以点击试试

 
微信登录授权

如果是这样的页面的话,那么就没问题了,我们来到了用户授权页面。这里的域名是微信的域名。用户在这里扫码之后确认授权,我们就可以继续下面的步骤。

4.微信回调

这里我们要注意,用户不一定非要授权你的网站,所以我们需要确定用户是否授权。

无论用户是否授权微信都回重定向到我们之前预留的回调地址中,并且带者一个叫code的随机字符串(如果之前拼接url时添写了STATE,也会返回这个数据)。
如果用户没有授权则没有code这个数据,我们就根据这个判断

        //获取code
        $code = I('get.code');
        //如果没有code则返回首页
        if (empty($code)) {
            $this->redirect(U('/'));
            die();
        }
二.开始登录

我们根据文档知道,这个code 是用于换取access_token用的。文档提示我们需要使用get方式带着code和app_id和secret来请求token。我们当然不能用重定向这样的方法去获取。所以我们选择比较高效的curl,看过我上一篇笔记的朋友都会知道,微博为我们提供了很强大的sdk,我们只需要条用sdk中的get_accessToken()方法就好了,他已经帮我们把curl写好了。既然腾讯没有这么好的服务,就只有我们自己来了

  1. 封装自己的curl方法
 /**
     * @param $url 地址
     * @param $method 请求方式
     * @param null $postfields post的数据
     * @param array $headers 请求头
     * @param bool $debug 调试模式
     * @return array
     */
    private function http($url, $method, $postfields = null, $headers = array(), $debug = false)
    {
        $ci = curl_init();
        /* Curl settings */
        curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ci, CURLOPT_TIMEOUT, 30);
        curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);

        switch ($method) {
            case 'POST':
                curl_setopt($ci, CURLOPT_POST, true);
                if (!empty($postfields)) {
                    curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
                    $this->postdata = $postfields;
                }
                break;
        }
        curl_setopt($ci, CURLOPT_URL, $url);
        curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ci, CURLINFO_HEADER_OUT, true);

        $response = curl_exec($ci);
        $http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);

        if ($debug) {
            echo "=====post data======
";
            var_dump($postfields);

            echo '=====info=====' . "
";
            print_r(curl_getinfo($ci));

            echo '=====$response=====' . "
";
            print_r($response);
        }
        curl_close($ci);
        return array($http_code, $response);
    }

当然拉,这个也不是我自己写的,是在tp论坛中发现一个大神写的,我就拿来用咯,返回值是一个数组,第一个元素是状态码,我们都知道200是正确连接的意思,第二个元素就是curl返回的数据

  1. 请求token
//拼接url
 $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$wxConfig['app_id']}&secret={$wxConfig['app_secret']}&code={$code}&grant_type=authorization_code";
      //调用curl方法得到返回值
        $result = $this->http($url, 'get');
    //判断请求状态是否正确
        if ($result[0] == 200) {
            //将json数据转换为数组,得到accesstoken等数据
            $arr = json_decode($result[1],true);
        }

这样我们就获取到了一个包含accessToken的数组
这个数组里面有


 
正确的返回
  1. 获取用户数据

其实微信和qq一样,没有多少返回数据,有价值的数据更少。不过谁让他用户多嘛,我们还是得做

我选择得是将获取userInfo封装到模型上,方便调用

      //实例化模型,没有用过tp3.2.3的朋友不用太在意,总之就是实例化模型就对了
       $synModel = D('SyncLogin');
      //调用模型上的wechat方法,传入我们刚刚获取到的accessToken,openId,refreshToken
       $userInfo = $synModel->wechat($arr['access_token'], $arr['openid'],$arr['refresh_token']);

下面我们看下获取用户信息的方法


    /**
     * 微信获取用户数据
     * @param $token
     * @param $openid
     * @param $refresh_token
     * @return array
     */
    public function wechat($token, $openid, $refresh_token)
    {
        //拼接获取用户信息的url
        $url = 'https://api.weixin.qq.com/sns/userinfo?access_token=' . $token . '&openid=' . $openid;
        //发送curl请求,获取返回数据
        $result = $this->http($url, 'get');
        //判断请求状态
        if ($result[0] == 200) {
            //将返回的数据整理成数组
            $arr = json_decode($result[1], true);
            //如果数组中含有键名为errcode,且值等于41001,则说明token过期
            if (array_key_exists('errcode', $arr) && $arr['errcode'] == 41001) {
                //调用刷新token方法,并返回
                return $this->refreshToken($refresh_token);
            } else {
                //没有过期则返回用户的信息
                return $arr;
            }
        } else {
            //请求失败
            return false;
        }
    }

刚才的代码中有用到一个刷新token的方法,这个和获取token大同小异,同样是微信提供的接口,我们配置好了url直接curl访问就是了

    /**
     * 刷新token
     * @param $refresh_token
     * @return bool|mixed
     */
    public function refreshToken($refresh_token)
    {
      //获取配置文件的中的数据,没用过的没关系,就是获取配置文件中的配置
        $wxConfig = C('WX_LOGIN');
        $url = 'https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=' . $wxConfig['app_id'] . '&grant_type=refresh_token&refresh_token=' . $refresh_token;
        $result = $this->http($url, 'get');
        if ($result[0] == 200) {
            return json_decode($result[1], true);
        } else {
            return false;
        }
    }
三. 业务逻辑

这样我们就获取到了微信用户的用户数据了,剩下的其实就是属于业务逻辑了,我就不贴代码了。每个公司的业务逻辑都有可能不一样。我就介绍下思路,供大家参考

 
第三方登录.png

好了,本次微信第三方登录的介绍了就写到这里了,如果有什么地方不对,希望大神指正.谢谢

以摘自简书https://www.jianshu.com/p/2178764d0e21

原文地址:https://www.cnblogs.com/qaing123/p/8693907.html