PHP项目QQ登录接口调用实现全指南:从申请到集成
目录导读
QQ登录接口概述与原理
QQ登录接口是腾讯开放平台提供的OAuth2.0授权协议实现,允许用户通过QQ账号快速登录第三方网站,当前主流接口版本为QQ互联V3.0,支持移动端与PC端接入。

核心原理:用户授权后,开发者通过接口获取Access Token(访问令牌),再凭令牌获取用户唯一标识OpenID及昵称、头像等信息,整个过程无需用户提供密码,安全性较高。
技术栈要求:PHP 5.6+,需开启cURL扩展,支持Session或Redis等会话存储。
前期准备:申请QQ互联开发者与应用
1 注册开发者账号
- 访问 [QQ互联官网](域名未列出,请自行搜索“QQ互联”)
- 点击“注册”,填写个人/企业信息,完成实名认证(通常1-2个工作日审核)
2 创建应用
- 登录后选择“应用管理” → “创建应用”
- 填入应用名称、应用图标(128×128px以上)
- 回调域名:填写你的PHP项目域名(如
www.example.com,无需带http://) - 提交后获取APP ID与APP Key,务必妥善保存
3 安全设置
- 启用IP白名单:仅允许服务器IP调用接口
- 配置状态参数(state) 防CSRF攻击(后续代码会实现)
核心流程:OAuth2.0授权三步走
1 第一步:获取Authorization Code
用户点击“QQ登录”按钮后,跳转至QQ授权页面:
// 构建授权URL
$app_id = '你的APP_ID';
$redirect_uri = urlencode('https://www.example.com/qq_callback.php');
$state = md5(uniqid(rand(), true)); // 生成随机state
// 存储state到session用于验证
session_start();
$_SESSION['qq_state'] = $state;
$auth_url = "https://graph.qq.com/oauth2.0/authorize?response_type=code" .
"&client_id={$app_id}" .
"&redirect_uri={$redirect_uri}" .
"&state={$state}" .
"&scope=get_user_info";
header("Location: $auth_url");
关键参数:
scope=get_user_info:仅获取基本信息,不需额外权限state:必须与回调时比对,防止伪造请求
2 第二步:回调处理,换取Access Token
用户授权后返回回调页,需校验state并获取code:
session_start();
if ($_GET['state'] !== $_SESSION['qq_state']) {
die('state不匹配,请求非法');
}
$code = $_GET['code']; // 授权临时票据
$app_id = '你的APP_ID';
$app_key = '你的APP_KEY';
$redirect_uri = urlencode('https://www.example.com/qq_callback.php');
// 请求Access Token
$token_url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code" .
"&client_id={$app_id}" .
"&client_secret={$app_key}" .
"&code={$code}" .
"&redirect_uri={$redirect_uri}";
$response = file_get_contents($token_url);
parse_str($response, $params);
$access_token = $params['access_token'];
3 第三步:获取用户OpenID与信息
// 获取OpenID(用户唯一标识)
$openid_url = "https://graph.qq.com/oauth2.0/me?access_token={$access_token}";
$response = file_get_contents($openid_url);
$result = json_decode(substr($response, 10, -3), true); // 去除callback包裹
$openid = $result['openid'];
// 获取用户信息
$user_info_url = "https://graph.qq.com/user/get_user_info?" .
"access_token={$access_token}" .
"&oauth_consumer_key={$app_id}" .
"&openid={$openid}";
$user_info = json_decode(file_get_contents($user_info_url), true);
echo "QQ昵称:" . $user_info['nickname'];
echo "头像:" . $user_info['figureurl_qq_2']; // 100x100px
PHP代码实现:获取Access Token与用户信息
1 完整封装类代码
class QQLogin {
private $app_id;
private $app_key;
private $redirect_uri;
public function __construct($app_id, $app_key, $redirect_uri) {
$this->app_id = $app_id;
$this->app_key = $app_key;
$this->redirect_uri = $redirect_uri;
}
// 生成授权链接
public function getAuthUrl() {
$state = md5(uniqid(rand(), true));
$_SESSION['qq_state'] = $state;
return "https://graph.qq.com/oauth2.0/authorize?response_type=code" .
"&client_id={$this->app_id}" .
"&redirect_uri=" . urlencode($this->redirect_uri) .
"&state={$state}" .
"&scope=get_user_info";
}
// 回调处理,返回用户信息
public function callback($code, $state) {
if ($state !== $_SESSION['qq_state']) {
throw new Exception('state验证失败');
}
// 获取token
$token = $this->_getAccessToken($code);
// 获取openid
$openid = $this->_getOpenId($token);
// 获取用户信息
$userInfo = $this->_getUserInfo($token, $openid);
return [
'openid' => $openid,
'nickname' => $userInfo['nickname'],
'avatar' => $userInfo['figureurl_qq_2'],
'gender' => $userInfo['gender']
];
}
private function _getAccessToken($code) {
$url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code" .
"&client_id={$this->app_id}" .
"&client_secret={$this->app_key}" .
"&code={$code}" .
"&redirect_uri=" . urlencode($this->redirect_uri);
$response = file_get_contents($url);
parse_str($response, $params);
return $params['access_token'];
}
private function _getOpenId($access_token) {
$url = "https://graph.qq.com/oauth2.0/me?access_token={$access_token}";
$response = file_get_contents($url);
$result = json_decode(substr($response, 10, -3), true);
return $result['openid'];
}
private function _getUserInfo($access_token, $openid) {
$url = "https://graph.qq.com/user/get_user_info?" .
"access_token={$access_token}" .
"&oauth_consumer_key={$this->app_id}" .
"&openid={$openid}";
return json_decode(file_get_contents($url), true);
}
}
2 调用示例
session_start();
$qq = new QQLogin('APP_ID', 'APP_KEY', 'https://www.example.com/qq_callback.php');
// 步骤1:点击登录
if ($_GET['action'] == 'login') {
header("Location: " . $qq->getAuthUrl());
}
// 步骤2:回调处理
if ($_GET['code']) {
try {
$user = $qq->callback($_GET['code'], $_GET['state']);
// 存入数据库或session
$_SESSION['qq_user'] = $user;
echo "登录成功,欢迎:" . $user['nickname'];
} catch (Exception $e) {
echo "登录失败:" . $e->getMessage();
}
}
常见问题与解决方案
1 报错:redirect_uri与后台配置不一致
原因:回调域名末尾多写了路径,或未带协议。
解决:检查QQ互联后台的“回调域名”是否包含实际路径(如www.example.com,不带http://),且代码中的redirect_uri必须完全匹配(包括路径)。
2 无法获取用户信息(返回code:100020)
原因:Access Token已过期(有效期通常30天),或OpenID不匹配。
解决:重新走授权流程获取新token;检查oauth_consumer_key是否为APP ID。
3 用户头像获取失败
可能原因:CDN地址被屏蔽。
建议:使用figureurl_qq_2(100px)或figureurl_qq_1(40px)降级处理。
4 file_get_contents报错
替代方案:改用cURL库,兼容性更好:
function curl_get($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
问答环节
Q1:QQ登录接口支持移动端吗?
A:支持,移动端只需将get_user_info接口的figureurl_qq_2替换为figureurl_qq(头像尺寸自适应),若需手机号,需额外申请“获取手机号”权限(企业认证)并使用get_mobile接口。
Q2:如何防止重复绑定QQ账号?
A:在回调逻辑中查询数据库:SELECT user_id FROM qq_bind WHERE openid = ?,若已存在则直接登录该用户;否则创建新用户并绑定。
Q3:Access Token过期后如何处理?
A:QQ没有提供Refresh Token机制,只能通过静默授权重新获取,建议:
- 每次登录时都重新请求Authorization Code(用户主动点击登录)。
- 或使用
http://graph.qq.com/user/get_unionid接口获取UnionID(需在QQ互联后台申请),该ID不变,可永久关联用户。
Q4:接口响应慢怎么办?
A:海外服务器建议使用腾讯云国内节点加速;本地缓存用户信息(如redis),设定10分钟过期,避免每次请求都调用QQ接口。
Q5:能同时支持微信登录与QQ登录吗?
A:可以,只需分别申请微信开放平台与QQ互联的应用,在登录页面提供两个按钮,后端分别走各自的OAuth2.0流程即可。
PHP项目集成QQ登录接口的核心是理解OAuth2.0的三步授权过程,注意state防篡改与回调域名配置,建议使用封装类管理凭证,并加入异常处理,如需批量部署,可将APP_ID、APP_KEY写入环境变量,代码调试时可用浏览器F12查看网络请求,确保跳转链接参数完整。