第三方登录之QQ登录从入门到填坑
- 目录
- 1. 前言
- 2. 回顾OAuth协议基本原理
- 3. 接入QQ登录SDK
- 3.1接入前的条件和开放平台账号申请
- 3.2引入官方SDK
- 3.2.1SDK参数配置
- 3.2.2SDK核心方法解读
- 3.3整合QQ登录SQK到应用中
- 3.3.1SDK优化处理
- 3.3.2调用API开发实例
1.前言
之前写了一篇关于微信登录的实战文章,发现挺多人看的,下面把微信的粑粑(QQ)也整理一下,首先登陆QQ互联首页(https://connect.qq.com/)进行个人/企业认证。大概审核时间在一周左右。认证通过之后创建应用,这里主要用到应用的APP ID 和 APP Key 这两个参数。当然还需要填写一下回调地址,就是请求qq接口获取code参数回调给你的地址,话不多说,我们开始QQ登录之旅吧。
代码分享:https://github.com/mtdgclub/qqlogin
2.回顾OAuth协议基本原理
OAuth 就是一种授权机制。数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据。系统从而产生一个短期的进入令牌(token),用来代替密码,供第三方应用使用。
PS:只要知道了令牌,就能进入系统。系统一般不会再次确认身份,所以令牌必须保密,泄漏令牌与泄漏密码的后果是一样的。 这也是为什么令牌的有效期,一般都设置得很短的原因。
比如QQ登录授权:
3.接入QQ登录SDK
3.1接入前的条件和开放平台账号申请
- 官网:http://connect.qq.com
- 申请AppID和AppKey
- 配置好回调地址
3.2引入官方SDK
前往官网下载你熟悉编程语言的SDK,这边默认是PHP,所以phper可以在我的代码分享直接使用QQ_PHP_SDK_v2.2.zip包。
3.2.1SDK参数配置
- 务必在QQ开放平台设置好回调地址,然后再项目文件下写好回调地址的文件callback.php
- 访问SDK包,配置SDK参数,配置完成后删除冗余文件剩下API文件夹
3.2.2 SDK核心方法解读
登录授权相关的三个主要类
- 配置读写与SESSION存取Recorder.class.php
//-------读取配置文件
$incFileContents = file(ROOT."comm/inc.php");
$incFileContents = $incFileContents[1];
$this->inc = json_decode($incFileContents);
- 基于CURL库的get和post请求URL.class.php
//combineURL拼接URL函数
foreach($keysArr as $key => $val){
$valueArr[] = "$key=$val";
}
//使用&拼接参数键值对
$keyStr = implode("&",$valueArr);
$combined .= ($keyStr);
- get方式请求资源
public function get($url, $keysArr)
- post方式请求资源
public function post($url, $keysArr, $flag = 0)
- Oauth相关URL动态拼接与token操作Oauth.class.php
/**
* 拼接QQ登录URL
*/
public function qq_login(){...}
3.3整合QQ登录SQK到应用中
3.3.1SDK优化处理
优化目的:
- SDK太老,无人维护,我们需要调整文件和目录结构
- SDK中常量名可能与我们项目冲突,批量替换SDK常量名称
将comm文件夹内的文件分别移动代码到指定的文件里面,最终实现删除comm文件夹的效果,然后再入口文件修改常量的定义名称,记得全文搜索,避免与以后项目起冲突,具体请看我修改好的sdk文件夹,步骤如下:
- 将常量CLASS_PATH替换成QQ_CONNECT_SDK_CLASS_PATH
- 在qqConnectAPI.php定义常量
define("QQ_CONNECT_SDK_CLASS_ROOT",dirname(__FILE__)."/");
define("QQ_CONNECT_SDK_CLASS_PATH",QQ_CONNECT_SDK_CLASS_ROOT."class/");
- 删除comm文件
- 删除qqConnectAPI.php的配置引入
//require_once(dirname(__FILE__)."/comm/config.php");
- 在Recorder.class.php中添加配置信息代码
//-------读取配置文件 优化代码
$this->inc->appid = '';
$this->inc->appkey = '';
$this->inc->callback = QQ_CONNECT_SDK_ROOT . 'callback.php';
$this->inc->scope = 'get_user_info';
$this->inc->errorReport = true;
$this->inc->storageType = 'file';
3.3.2调用API开发实例
- debug调试输出函数,详见debug.php文件
<?php
/**
* 调式输出函数
* @param mix $val 调试输出源数据
* @param bool $dump 是否启用var_dump调式
* @param bool $exit 是否在调试结束后设置断点
*/
function debug($val, $dump = false, $exit = true)
{
//自动获取调试函数名称$func
if ($dump) {
$func = 'var_dump';
} else {
$func = (is_array($val) || is_object($val)) ? 'print_r' : 'printf';
}
//输出到html
header('Content-type:text/html;charset=utf-8');
echo '<pre>debug output:<hr/>';
$func($val);
echo '</pre>';
if ($exit) exit();
}
- 访问qq登陆页面,详见qqlogin.php
<?php
require_once 'debug.php';
require_once 'qqLoginSDK/qqConnectAPI.php';
//访问qq登陆页面
$oauth = new Oauth();
$oauth->qq_login();
- 在回调地址中获得code和accesstoken,通过accesstoken获得openID,详见callback.php
<?php
require_once 'debug.php';
require_once 'qqLoginSDK/qqConnectAPI.php';
$code = $_GET['code'];
//请求accesstoken
$oauth = new Oauth();
$accessToken = $oauth->qq_callback();
//获得openID
$openid = $oauth->get_openid();
//存储到cookie
setcookie('qq_accesstoken', $accessToken, time() + 86400);
setcookie('qq_openid', $openid, time() + 86400);
header('location:index.php');
注意:openID是QQ用户在第三方站点的唯一标识,同一个QQ用户在不同站点使用QQ登录openID始终一样
- 获得用户数据并存储到本地数据库,详见index.php
$qc = new QC($_COOKIE['qq_accesstoken'], $_COOKIE['qq_openid']);
$userinfo = $qc->get_user_info();
debug($userinfo);