多个不同域名共用一个QQ登录实例教程

星空幻颖

简介

本篇教程不仅仅是qq登录教程,关键问题还有解决一个多域名共用一个qq登录问题。

网站做大了,很多网站开始给用户提供一个二级域名的主页。或者自己本身就有很多二级域名子站。而腾讯申请qq登录时候,并不能把这些二级域名都加入允许的域名列表。毕竟很多情况下还不确定二级域名。

这个时候,我们也不能申请很多qq登录,不现实。今天主要就讲解下此种情况下的解决方案。

域名转换

解决该问题的一个核心方法就是域名转换。就是在qq登录之前,先跳转到具有qq登录权限的域名下。让其帮我获取信息,之后再跳转回原域名。

图片描述

假设我有一个可以qq登录的域名:bidianer.com。当我处于一个其他域名或者二级域名的时候,假设是weiya.me,这个时候我直接跳转腾讯,肯定是有问题的。

所以,第一步我先从weiya.me跳转bidianer.com域名下面的一个方法,然后通过bidianer.com下的方法进行一次跳转,获取到code后。跳转回之前域名weiya.me,同时在url中带上code,这样就和从腾讯那里过来的一样。

这里解释下为什么拿到code之后万事大吉。因为,拿到code之后,你获取用户信息什么的,腾讯是不限制来源域名的。哪怕你web版本拿到,你到app去请求也没人管你。

转换实现

HOST转换

我们这里使用Thinkphp框架实现,因为用的人多,第二个因为简单,看看猜猜就会了。

由于这个会经常使用,我们放在model里面

新建一个AuthModel.class.php模型,新建一个transferHost转换的方法

首先确定一个具有qq登录权限域名。

$open_host = 'bidianer.com'; // 开放平台绑定的域名

第二步,确定当前的域名是否具有登录权限,如果没有,我们就跳转下。

// 确定当前的域名HOST
$curr_host = $_SERVER['HTTP_HOST']; // 当前页面的域名

// 比较当前域名是否和绑定的域名一致,就是看看是否具有权限而已
if ($curr_host && ($open_host != $curr_host))
{
    $jump_url = "http://".$open_host."/".$_SERVER['PATH_INFO']."?backhost=".$curr_host;
    redirect($jump_url);
}

这里好好的讲讲那个条件判断,

$curr_host && ($open_host != $curr_host)

这里首先确认获取到了当前HOST然后和绑定的$open_host比较下,如果当前我们就在bidianer.com,那么不会执行跳转。否则就会跳转。

下面我们看下跳转的链接。

"http://".$open_host."/".$_SERVER['PATH_INFO']."?backhost=".$curr_host;

其中$open_host是开放平台绑定的域名,也就是具有qq登录权限的域名,这里是bidianer.com

而域名后面加上的是$_SERVER['PATH_INFO']也就是还是跳转到bidianer.com下面的和当前方法一样的方法。这就需要weiya.mebidianer.com两个服务器代码完全相同。

还有一点,跳转时候,后面跟着一个参数backhost。他的取值是当前网站的HOST也就是weiya.me。这时为了之后跳转回来做准备的。所以,我们还需要将该参数保存下来。放入session或者放入qq登录url的state参数。

补充一点,qq登录的state参数,你传过去的值,从qq跳转回来会原封不动的带回来。

这里我们给一下完整的转换代码

public function transferHost(){
    $open_host = 'bidianer.com'; // 开放平台绑定的域名
    $curr_host = $_SERVER['HTTP_HOST']; // 当前页面的HOST
    $back_host = I("param.backhost"); // 获取返回链接
    if ($curr_host && ($open_host != $curr_host))
    {
        $jump_url = "http://".$open_host."/".$_SERVER['PATH_INFO']."?backhost=".$curr_host;
        redirect($jump_url);
    }
    $redirect_uri = urlencode('http://bidianer.com/sign/qqCallBack'); // 这里是qq待会跳转回来的地址,自定义
    
    // 这里是获取qq登录地址,直接跳转去qq了(可以看下面教程)
    $url = $this->getQQLoginUrl($back_host , $redirect_uri);
    redirect($url);
}

获取qq登录跳转链接

执行完跳转操作后,我们现在一定在具有登录权限的域名下。所以我们获取qq登录链接准备跳转腾讯qq。

这个官方很详细给了文档,简单。直接给代码

/**
 * 获取QQ登录所需要的URL
 * @param string $back_host 当前所处的实际域名地址,这里是weiya.me。qq跳转回bidianer.com,还需要跳转回$back_host
 * @param string $redirect_uri qq登录跳转回来的地址
 * @return string
 */
public function getQQLoginUrl($back_host , $redirect_uri)
{
    $qq_conf = C("QQ_LOGIN");//这里是appid,我写在配置了,隐私问题也就不写出来了
    $url ='https://graph.qq.com/oauth2.0/authorize';
    
    // 下面内容放入state,如果有back_host,也就是在weiya.me,qq跳转回后还要再跳一次。如果没有,那么就说明在bidianer.com
    $state = $back_host ? base32_encode($back_host) : base32_encode($_SERVER['HTTP_HOST']);
    $scope = 'get_user_info';
    return $url.'?response_type=code'
    . '&client_id='.$qq_conf['APPID']
    . '&redirect_uri='.$redirect_uri
    . '&scope='.$scope
    . '&state='.$state;
}

控制器代码

到这里为止,准备去qq获取信息的部分就完成了,下面给出controller代码。其实也就是调用model代码。

/**
 * QQ 登录
 */
public function inByQQ()
{
    $this->authModel->transferHost();
}

QQ登录回跳

返回原域名

上面的步奏以后,第一步code信息已经获取到。我们首先从url中取出statecode

  • state:我们之前放入的原域名地址。

  • code:微信给我们获取信息的钥匙。

从qq回来后,我们其实还在bidianer.com的域名下。这个时候我们还要验证下,原始域名是否是bidianer.com,如果不是,跳转回原域名。

方法类似之前从原域名跳过来的,只不过反过来而已。所以我们新建方法unTransferHost。反解,不知道这么写对不对。图片描述

/**
 * 还原域名转换,从一级域名回转到之前的二级或者三级域名
 * 解决第三方登录问题,登录完成后跳回企业域名下
 * @return bool
 */
public function unTransferHost()
{
    $state = I("get.state");
    $code = I("get.code");

    if ($state)
    {
        $host = base32_decode($state);
        if ($host && ($host != $_SERVER['HTTP_HOST']))
        {
            // 这里记得要带上code,我们忙这么大一圈就是为了这个code
            $jump_url = "http://".$host."/".$_SERVER['PATH_INFO']."?code=".$code; 
            redirect($jump_url); // 返回原域名了
        }
    }

    // 这边也放了一份session,不过没啥鸟用
    session("qq_code",$code);
    return $code;
}

获取用户信息

这个时候,我们从bidianer.com到了weiya.me域名。而且我们也获取了code。这个时候,我们可以获取下一步信息了。

下面就简单了。

我们直接给出控制器代码。

/**
 * qq回跳地址
 */
public function qqCallBack()
{
    // 这里就是上面的内容,反转换
    $code = $this->authModel->unTransferHost();
    $open_info = $this->authModel->getQQUserInfo($code);
}

控制器中的getQQUserInfo如下:

/**
 * 获取qq绑定用户的第三方信息
 * @param $code
 * @return array|int
 */
public function getQQUserInfo($code)
{
    // 这里是封装的curl请求,相信你都开始做qq登录开发了,这个肯定会。
    $curl = new Curl();
    $qq_conf = C("QQ_LOGIN");// appid和key我写在配置里了,你们要用你们的。
    $get_token_url ='https://graph.qq.com/oauth2.0/token?code='.$code.'&client_id='.$qq_conf['APPID'].'&client_secret='.$qq_conf['APPKEY'].'&grant_type=authorization_code&redirect_uri='.C('REDIRECT_URI');
    $result = $curl->get($get_token_url);
    parse_str($result, $param);

    // 连接失败
    if (!$param['access_token'])
    {
        return -1;
    }

    $get_opid_url = 'https://graph.qq.com/oauth2.0/me?access_token='.$param['access_token'];

    $opid = $curl->get($get_opid_url);
    $opid_param = json_decode(substr(trim($opid), 9, -2), true);

    // 连接失败
    if (!$opid_param['openid'])
    {
        return -2;
    }

    $qq_conf = C("QQ_LOGIN");
    $curl = new Curl();
    $firstChar = new StringFristChar();
    $GLOBALS['CRULOPT_SSL'] = false; // 必须指定 CURL 的 SSL 参数为 false 才能正常使用 QQ 的接口
    $url = "https://graph.qq.com/user/get_user_info?openid=".$opid_param['openid']."&access_token=".$param['access_token']."&oauth_consumer_key=".$qq_conf['APPID'];
    $rst = $curl->get($url);
}

获取到信息后大概是这个样子:

$qq_info = [
    "ret" => 0,
    "msg" => "",
    "is_lost" => 0,
    "nickname" => '严颖',
    "gender" => "男",
    "province" => "江苏",
    "city" => "南京",
    "year" => "1992",
    "figureurl" => "http://qzapp.qlogo.cn/qzapp/101218247/BC5B732892966E8FFBD48763B431C2B3/30",
    "figureurl_1" => "http://qzapp.qlogo.cn/qzapp/101218247/BC5B732892966E8FFBD48763B431C2B3/50",
    "figureurl_2" => "http://qzapp.qlogo.cn/qzapp/101218247/BC5B732892966E8FFBD48763B431C2B3/100",
    "figureurl_qq_1" => "http://q.qlogo.cn/qqapp/101218247/BC5B732892966E8FFBD48763B431C2B3/40",
    "figureurl_qq_2" => "http://q.qlogo.cn/qqapp/101218247/BC5B732892966E8FFBD48763B431C2B3/100",
    "is_yellow_vip" => "0",
    "vip" => "0",
    "yellow_vip_level" => "0",
    "level" => "0",
    "is_yellow_year_vip" => "0",
];

图片描述

阅读 4.4k

2.6k 声望
263 粉丝
0 条评论
你知道吗?

2.6k 声望
263 粉丝
宣传栏