thinkPHP5项目中实现QQ第三方登录功能


Posted in PHP onOctober 20, 2017

本文实例讲述了thinkPHP5项目中实现QQ第三方登录功能。分享给大家供大家参考,具体如下:

最近用thinkPHP 5框架做了一个婚纱店的项目,在开发过程中需要用到第三方登录,腾讯官方给的案例是几个文件相互包含实现的,放到tp5里面很悲催的发现在控制器中不能通过include或者require完成预期功能,想要用腾讯官方封的类就必须对其进行修改,修改如下:

1. 找到官方SDK里面的核心文件

thinkPHP5项目中实现QQ第三方登录功能

框架外使用的时候是include 'qqConnectAPI.php',打开这个文件可以看到它是包含了另外几个文件的,comm文件夹下的几个文件无非就是定义一些常量,记录一下你的APP KEY这些信息,都无关紧要,只要把class文件夹下的几个类文件放到tp5里面就好了,而且仔细看一下代码会发现其实只要拿到三个类就完全可以实现功能了。

2. 放到tp框架里

tp5推荐将第三方的东西,同时又不是composer安装的统一放到extend目录下,因为可能以后还要做其他扩展,这里将qq登录相关的单独建一个qqlogin文件夹,

thinkPHP5项目中实现QQ第三方登录功能

可以看到里面只有三个类,我去掉了一个Recorder和一个ErrorCase类,见名知意,这两个的作用是记录一些信息,如access_token,还有异常处理,这里我就直接删掉了。另外注意,按照psr4规范,类名要跟文件名一致,所以要把文件名改一下,同时加上命名空间extend\qqlogintp5所有的类都要有命名空间

另外为了防止tp5找不到我们需要的文件,最好在config.php文件里注册一条根命名空间,在第30行:

// 注册的根命名空间
'root_namespace'  => [
 'extend\qqlogin' => '../extend/qqlogin/',
 'extend\baidu' => '../extend/bdlogin/'
],

3. 改造源代码

因为QC.php是继承了Oauth.php,我们从后者改起,去掉require_once,加上命名空间这个就不说了,首先看成员属性,类常量是腾讯平台的地址,不用管,原来有三个属性,recorder、error不需要,注释掉或直接删掉。下文同样,要想象跟这两个单词有仇,看到就注释或删掉。

// protected $recorder;
public $urlUtils;
// protected $error;
public $state;
public $appid = "****";
public $callback = "http://****/index/user/qqcallback";
public $scope = "get_user_info";

下面四个属性是需要添加的,state用于防止CSRF攻击,下面三个看官方文档就知道是什么东西了,这些原来是在comm文件夹下的inc.php存放的,现在直接拿过来变成成员属性。

然后构造函数,实例化三个类,有两个已经不存在了,而且上面说了,跟这两个单词有仇,看到就要注释或删掉。

再看下面的第一个成员方法qq_login()

public function qq_login(){
 $appid = $this->recorder->readInc("appid");
 $callback = $this->recorder->readInc("callback");
 $scope = $this->recorder->readInc("scope");
 //---生成唯一随机串防CSRF攻击
 $state = md5(uniqid(rand(), TRUE));
 $this->recorder->write('state',$state);
 *
 *
 return $login_url;
 // header("Location:$login_url");
}

我们已经有仇把有那两个单词的这几行删掉了,我们又需要这些东西,不要忘了我们上面增加了三个成员属性,这些值我们已经有了下面用的时候通过$this->appid就好了。state验证的时候我们可以通过session去验证,在tp5里面提供了助手函数去写session:

session('state',$this->state);

最后一句是header跳转,暂不知道什么原因在tp5里面并不能看到跳转效果,于是直接将url返回,再在控制器里面通过tp5的重定向函数$this->redirect()实现跳转。

下面看qq_callback()

public function qq_callback(){
 // $state = $this->recorder->read("state");
 //---验证state防止CSRF攻击
 if(input('state') != session('state')){
  // $this->error("30001");
  exit('30001');
 }
 *
 *
 // return $params["access_token"];
 session('access_token',$params["access_token"]);
}

出现那两个单词的已经注释了,我们在qq_login里面有写session,这里直接取sessio比较就行了,input()也是tp5的助手函数,可以获得get、post请求的参数,结果是一个数组,但是不能够再动态为其添加键值对,想要添加的话必须将其赋给一个变量,再对变量进行操作。这里有错误的话直接exit打印出错误号,官方文档有详细的错误号说明。在最后也是直接将获取到的access_token写进session。

下面的get_openid()方法类似,参数列表用session构建,返回值直接写进session。

然后再修改QC.php,只需修改构造方法,把数组的三个变量给一下值就好了。

$this->keysArr = array(
 "oauth_consumer_key" => (int)$this->appid,
 "access_token" => session('access_token'),
 "openid" => session('openid')
);

4. 控制器调用

改造完成,可以在控制器里面使用了,附上代码入下:

use extend\qqlogin\QC;
// 处理qq登录
public function qqlogin()
{
 $qq = new QC();
 $url = $qq->qq_login();
 $this->redirect($url);
}
// qq登录回调函数
public function qqcallback(UserModel $user)
{
 $qq = new QC();
 $qq->qq_callback();
 $qq->get_openid();
 $qq = new QC();
 $datas = $qq->get_user_info();
 * // 拿到用户信息后的处理
 *
}

切记:

在回调函数里面要实例化两次QC才能拿到用户信息,第二次实例化的时候才有openidaccess_token两个参数。

希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。

PHP 相关文章推荐
使用 eAccelerator加速PHP代码的目的
Mar 16 PHP
php cc攻击代码与防范方法
Oct 18 PHP
PHP中mb_convert_encoding与iconv函数的深入解析
Jun 21 PHP
详解PHP匿名函数与注意事项
Mar 29 PHP
详解WordPress中添加友情链接的方法
May 21 PHP
PHP Header用于页面跳转时的几个注意事项
Oct 21 PHP
THinkPHP获取客户端IP与IP地址查询的方法
Nov 14 PHP
详解PHP文件的自动加载(autoloading)
Feb 04 PHP
Laravel框架实现调用百度翻译API功能示例
May 30 PHP
PHP+MySQL实现在线测试答题实例
Jan 02 PHP
php封装的page分页类完整实例代码
Feb 01 PHP
Laravel中如何轻松容易的输出完整的SQL语句
Jul 26 PHP
PHP简单实现二维数组赋值与遍历功能示例
Oct 19 #PHP
phpStudy2016 配置多个域名期间遇到的问题小结
Oct 19 #PHP
phpStudy配置多站点多域名方法及遇到的403错误解决方法
Oct 19 #PHP
PHP自定义函数实现数组比较功能示例
Oct 19 #PHP
phpstudy的php版本自由修改的方法
Oct 18 #PHP
phpStudy 2016 使用教程详解(支持PHP7)
Oct 18 #PHP
PHP实现重载的常用方法实例详解
Oct 18 #PHP
You might like
php zend 相对路径问题
2009/01/12 PHP
PHP将MySQL的查询结果转换为数组并用where拼接的示例
2016/05/13 PHP
CI框架常用函数封装实例
2016/11/21 PHP
微信公众号模板消息群发php代码示例
2016/12/29 PHP
jQuery 点击图片跳转上一张或下一张功能的实现代码
2010/03/12 Javascript
js实现弹窗插件功能实例代码分享
2013/12/12 Javascript
Javasipt:操作radio标签详解
2013/12/30 Javascript
ES6新特性:使用export和import实现模块化详解
2017/07/31 Javascript
Angular6 Filter实现页面搜索的示例代码
2018/12/02 Javascript
js实现随机点名程序
2020/09/17 Javascript
vuex刷新后数据丢失的解决方法
2020/10/18 Javascript
python中的多重继承实例讲解
2014/09/28 Python
Python中解析JSON并同时进行自定义编码处理实例
2015/02/08 Python
Python计算两个日期相差天数的方法示例
2017/05/23 Python
python删除过期log文件操作实例解析
2018/01/31 Python
Python拆分大型CSV文件代码实例
2019/10/07 Python
ubuntu 18.04 安装opencv3.4.5的教程(图解)
2019/11/04 Python
python交互模式基础知识点学习
2020/06/18 Python
Python 多进程、多线程效率对比
2020/11/19 Python
python matlab库简单用法讲解
2020/12/31 Python
HTML5 Canvas绘制圆点虚线实例
2015/01/01 HTML / CSS
重新定义牛仔布,100美元以下:Warp + Weft
2018/07/25 全球购物
navabi英国:设计师大码女装
2019/06/25 全球购物
母亲80寿诞答谢词
2014/01/16 职场文书
职工代表大会主持词
2014/04/01 职场文书
有关爱国演讲稿
2014/05/07 职场文书
小学优秀班集体申报材料
2014/05/25 职场文书
小学生环保标语
2014/06/13 职场文书
夫妻双方自愿离婚协议书
2014/10/24 职场文书
2014年发展党员工作总结
2014/11/12 职场文书
2015年感恩父亲节活动策划方案
2015/05/05 职场文书
2016继续教育培训学习心得体会
2016/01/19 职场文书
2019通用版导游词范本!
2019/08/07 职场文书
gateway与spring-boot-starter-web冲突问题的解决
2021/07/16 Java/Android
Nginx反向代理至go-fastdfs案例讲解
2021/08/02 Servers
Pygame Draw绘图函数的具体使用
2021/11/17 Python