ThinkPHP接入QQ互联实现登录的案例分析

本篇介绍了使用thinkphp接入qq互联实现第三方登录的方法,作为一个小案例来为各位讲解,希望对各位有帮助。

ThinkPHP接入QQ互联实现登录的案例分析

Thinkphp接入QQ互联实现登录的案例分析

我的一个二级域名项目想在也想接入QQ第三方登录功能,该项目采用的thinkphp5框架开发的项目,在网上搜了一些接入的案例,个人觉得鱼龙混杂不太适合自己,现在自己重新在thinkphp5框架上开发这个功能,下面是详细的开发步骤。

(推荐教程:thinkphp教程

第一步、下载QQ互联SDK,我们是基于thinkphp5框架下的,当然是要用PHP版的SDK,下载下来后的文件目录如下。

立即学习PHP免费学习笔记(深入)”;

ThinkPHP接入QQ互联实现登录的案例分析

第二步、将SDK主要目录上传到服务器合适的目录下,先说下SDK的主要的目录是API文件夹里面的class目录,当初为了做配置设置项测试,我上传了install文件夹,然后再开发环境配置了APP ID、APP Key以及callback_url,配置好之后会在API/comm文件夹中多处一个inc.php配置文件,最后再recorder类中会引用这个配置文件。可是在后面的 开发过程中我发现会报这个错The state does not match. You may be a victim of csrf。后面我把qqlogin方法里面的 state放到Session中,对官网的DEMO SDK已经完全失去信心了,不在用QQ互联全部的文件而是挑几个重要的类文件来做开发。后面想想官方给的SDK只是普通的PHP代码格式,我应用到thinkphp那很多东西都已经变了,最后我选择上个类文件,QC.php、URL.php、Oauth.php上传到extend/qqlogin目录下。在thinkphp5的项目中扩展类一般上传到extend文件夹下,如下图所示我上次的目录位置。

ThinkPHP接入QQ互联实现登录的案例分析

第三步、改造上述三个类文件,因为QC.php是继承了Oauth.php,我们从后者改起,去掉require_once,加上命名空间Namespace qqlogin,首先看成员属性,类常量是腾讯平台的地址,不用管,原来有三个属性,recorder、Error不需要,注释掉或直接删掉。下文同样,因为5个类文件我们只用到3个类文件,一个是报错类一个读取配置相关类。下面看Oauth.php成员属性、qqlogin跳转方法、qqcallback回调方法的,其他两个类文件没有太大的改大,按照上述规则改即可

<?php /* PHP SDK  * @version 2.0.0  * @author connect@qq.com  * @copyright © 2013, Tencent Corporation. All rights reserved.  */ namespace qqlogin; use qqlogin; class Oauth{     const VERSION = "2.0";     const GET_AUTH_CODE_URL = "https://graph.qq.com/oauth2.0/authorize";     const GET_ACCESS_TOKEN_URL = "https://graph.qq.com/oauth2.0/token";     const GET_OPENID_URL = "https://graph.qq.com/oauth2.0/me";     // protected $recorder;     public $urlUtils;     // protected $error;          function __construct(){         // $this->recorder = new Recorder();         $this-&gt;urlUtils = new URL();         // $this-&gt;error = new ErrorCase();     }     public function qq_login(){         // $appid = $this-&gt;recorder-&gt;readInc("appid");         // $callback = $this-&gt;recorder-&gt;readInc("callback");         // $scope = $this-&gt;recorder-&gt;readInc("scope");         $appid = $this-&gt;appid;         $callback = $this-&gt;callback;         $scope = $this-&gt;scope;         //-------生成唯一随机串防CSRF攻击         $state = md5(uniqid(rand(), TRUE));         // $this-&gt;recorder-&gt;write('state',$state);         session('state',$state);         //-------构造请求参数列表         $keysArr = array(             "response_type" =&gt; "code",             "client_id" =&gt; $appid,             "redirect_uri" =&gt; $callback,             "state" =&gt; $state,             "scope" =&gt; $scope         );         $login_url =  $this-&gt;urlUtils-&gt;combineURL(self::GET_AUTH_CODE_URL, $keysArr);         return $login_url;     }     public function qq_callback(){         // $state = $this-&gt;recorder-&gt;read("state");         //--------验证state防止CSRF攻击         if(input('state') != session('state')){             // $this-&gt;error-&gt;showError("30001");             exit('30001');         }         //-------请求参数列表         $keysArr = array(             "grant_type" =&gt; "authorization_code",             "client_id" =&gt; $this-&gt;appid,             "redirect_uri" =&gt; urlencode($this-&gt;callback),             "client_secret" =&gt; $this-&gt;appkey,             "code" =&gt; $_GET['code']         );         //------构造请求access_token的url         $token_url = $this-&gt;urlUtils-&gt;combineURL(self::GET_ACCESS_TOKEN_URL, $keysArr);         $response = $this-&gt;urlUtils-&gt;get_contents($token_url);         if(strpos($response, "callback") !== false){             $lpos = strpos($response, "(");             $rpos = strrpos($response, ")");             $response  = substr($response, $lpos + 1, $rpos - $lpos -1);             $msg = json_decode($response);             // if(isset($msg-&gt;error)){             //     $this-&gt;error-&gt;showError($msg-&gt;error, $msg-&gt;error_description);             // }         }         $params = array();         parse_str($response, $params);         // $this-&gt;recorder-&gt;write("access_token", $params["access_token"]);         // return $params["access_token"];         session('access_token',$params["access_token"]);     } }

第四步、编写控制器调用函数和回调函数,同时检查回调地址是否正确(回调地址是当你添加QQ第三方登录QQ互联返回跳转的地址,该地址携带重要参数,能获取最后用户的数据),有些时候如果你在QQ互联填写的回调地址与你控制器的不一样,那么最后就会卡在那个QQ互联填写的回调地址那,如www.100txy.com/index.php?code=65B7668A4F1BBB71DD0DF52B55AC1FC1&state=804e921e18e3545ecdf690316639c067。下面是控制器方法

use qqloginQC; // 处理qq登录     public function qqlogin(){         $qq = new QC();         $url = $qq-&gt;qq_login();         $this-&gt;redirect($url);     }     // qq登录回调函数     public function qqcallback(){         $qq = new QC();         $qq-&gt;qq_callback();         $qq-&gt;get_openid();         $qq = new QC();         $datas = $qq-&gt;get_user_info();         die(var_dump($datas));//为用户数据     }

值得注意的是在回调函数里面要实例化两次QC才能拿到用户信息,第二次实例化的时候才有openid和access_token两个参数。

更多Thinkphp教程,请关注thinkphp教程

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享