服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|JavaScript|易语言|

服务器之家 - 编程语言 - PHP教程 - PHP实现QQ快速登录的方法

PHP实现QQ快速登录的方法

2021-03-05 17:42时而宁靜 PHP教程

这篇文章主要为大家详细介绍了PHP实现QQ快速登录的3种方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

前言:

php实现qq快速登录,罗列了三种方法

方法一:面向过程,回调地址和首次触发登录写到了一个方法页面【因为有了if做判断】,

方法二,三:面向对象

1.先调用登录方法,向腾讯发送请求,
2.腾讯携带本网站唯一对应参数openid,accesstoken,返回到对应回调页面,
3.回调页面接受到腾讯的参数后,通过这个两个参数,再发出对应的请求,如查询用户的数据。
4.腾讯做出对应的操作,如返回这个用户的数据给你

即使你没看懂,也没关系,按照我下面的流程来,保证你可以实现。

前期准备:

使用人家腾讯的功能,总得和人家打招呼吧!

qq互联首页:http://connect.qq.com/

进入网址后,按如下操作来:

一.进入官网

PHP实现QQ快速登录的方法

二.申请创建【网站】应用

PHP实现QQ快速登录的方法

三.按要求填写资料

注意网站地址:填写你要设置快速登录的网址,eg:http://www.test.com;  

回调地址:填写你发送qq快速登陆后,腾讯得给你信息,这个信息往此页面接受。eg:http://www.test.com/accept_info.php

【详细的申请填写,请见官方提示,这里不做赘述】

PHP实现QQ快速登录的方法

四.申请成功后,完善信息

PHP实现QQ快速登录的方法

最终要求,获得app_id ,app_key

五.代码部分:

在你对应的php文件内写入,如下
方法一,面向过程法
使用方法:配置$app_id,$app_secret,$my_url后,其他原封复制即可,$user_data为返回的登录信息
代码:

 
?
1
 
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//应用的appid
   $app_id = "你的appid";
   //应用的appkey
   $app_secret = "你的appkey";
   //【成功授权】后的回调地址,即此地址在腾讯的信息中有储存
   $my_url = "你的回调网址";
 
   //step1:获取authorization code
   session_start();
   $code = $_request["code"];//存放authorization code
   if(empty($code))
   {
    //state参数用于防止csrf攻击,成功授权后回调时会原样带回
    $_session['state'] = md5(uniqid(rand(), true));
    //拼接url
    $dialog_url = "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id="
     . $app_id . "&redirect_uri=" . urlencode($my_url) . "&state="
     . $_session['state'];
    echo("<script> top.location.href='" . $dialog_url . "'</script>");
   }
 
   //step2:通过authorization code获取access token
   if($_request['state'] == $_session['state'] || 1)
   {
    //拼接url
    $token_url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&"
     . "client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url)
     . "&client_secret=" . $app_secret . "&code=" . $code;
    $response = file_get_contents($token_url);
    if (strpos($response, "callback") !== false)//如果登录用户临时改变主意取消了,返回true!==false,否则执行step3
    {
     $lpos = strpos($response, "(");
     $rpos = strrpos($response, ")");
     $response = substr($response, $lpos + 1, $rpos - $lpos -1);
     $msg = json_decode($response);
     if (isset($msg->error))
     {
      echo "<h3>error:</h3>" . $msg->error;
      echo "<h3>msg :</h3>" . $msg->error_description;
      exit;
     }
    }
 
    //step3:使用access token来获取用户的openid
    $params = array();
    parse_str($response, $params);//把传回来的数据参数变量化
    $graph_url = "https://graph.qq.com/oauth2.0/me?access_token=".$params['access_token'];
    $str = file_get_contents($graph_url);
    if (strpos($str, "callback") !== false)
    {
     $lpos = strpos($str, "(");
     $rpos = strrpos($str, ")");
     $str = substr($str, $lpos + 1, $rpos - $lpos -1);
    }
    $user = json_decode($str);//存放返回的数据 client_id ,openid
    if (isset($user->error))
    {
     echo "<h3>error:</h3>" . $user->error;
     echo "<h3>msg :</h3>" . $user->error_description;
     exit;
    }
    //echo("hello " . $user->openid);
    //echo("hello " . $params['access_token']);
 
    //step4:使用<span style="font-family: arial, helvetica, sans-serif;">openid,</span><span style="font-family: arial, helvetica, sans-serif;">access_token来获取所接受的用户信息。</span>
    $user_data_url = "https://graph.qq.com/user/get_user_info?access_token={$params['access_token']}&oauth_consumer_key={$app_id}&openid={$user->openid}&format=json";
     
    $user_data = file_get_contents($user_data_url);//此为获取到的user信息
    }
    else
    {
     echo("the state does not match. you may be a victim of csrf.");
    }

方法二,面向对象 使用类qq_loginaction.class
使用方法:
1.在qq_loginaction.class中正确配置 appid,appkey callback(回调网址)
2.在调用方法中,代码:

 
?
1
 
2
$qq_login = new \component\qq_loginaction();    //引入此类文件即可
$qq_login->qq_login();          //调用登录方法,向腾讯发出快速登录请求

3.在回调页面中,代码:

 
?
1
 
2
3
4
$qc = new \component\qq_loginaction();
$acs = $qc->qq_callback();<span style="white-space:pre">    //access_token
$oid=$qc->get_openid();<span style="white-space:pre">     //openid
$user_data = $qc->get_user_info();<span style="white-space:pre"//get_user_info()为获得该用户的信息,其他操作方法见api文档

4.$user_data即为返回的用户数据。
5.qq_loginaction.class.php 文件代码:【用的thinkphp3.2】

 
?
1
 
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
<?php
namespace component;
 
session_start();
define('appid','xxxx');   //appid
define('appkey','xxxx');  //appkey
define('callback','xxxx');  //回调地址
define('scope','get_user_info,list_album,add_album,upload_pic,add_topic,add_weibo');  //授权接口列表
class qq_loginaction {
 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";
 private $apimap = array(
  "get_user_info" => array(   //获取用户资料
   "https://graph.qq.com/user/get_user_info",
   array("format" => "json"),
  ),
  "add_t" => array(    //发布一条普通微博
   "https://graph.qq.com/t/add_t",
   array("format" => "json", "content","#clientip","#longitude","#latitude","#compatibleflag"),
   "post"
  ),
  "add_pic_t" => array(    //发布一条图片微博
   "https://graph.qq.com/t/add_pic_t",
   array("content", "pic", "format" => "json", "#clientip", "#longitude", "#latitude", "#syncflag", "#compatiblefalg"),
   "post"
  ),
  "del_t" => array(      //删除一条微博
   "https://graph.qq.com/t/del_t",
   array("id", "format" => "json"),
   "post"
  ),
  "get_repost_list" => array(    //获取单条微博的转发或点评列表
   "https://graph.qq.com/t/get_repost_list",
   array("flag", "rootid", "pageflag", "pagetime", "reqnum", "twitterid", "format" => "json")
  ),
  "get_info" => array(     //获取当前用户资料
   "https://graph.qq.com/user/get_info",
   array("format" => "json")
  ),
  "get_other_info" => array(    //获取其他用户资料
   "https://graph.qq.com/user/get_other_info",
   array("format" => "json", "#name-1", "#fopenid-1")
  ),
  "get_fanslist" => array(
   "https://graph.qq.com/relation/get_fanslist", //我的微博粉丝列表
   array("format" => "json", "reqnum", "startindex", "#mode", "#install", "#sex")
  ),
  "get_idollist" => array(
   "https://graph.qq.com/relation/get_idollist", //我的微博收听列表
   array("format" => "json", "reqnum", "startindex", "#mode", "#install")
  ),
  "add_idol" => array(
   "https://graph.qq.com/relation/add_idol",  //微博收听某用户
   array("format" => "json", "#name-1", "#fopenids-1"),
   "post"
  ),
  "del_idol" => array(   //微博取消收听某用户
   "https://graph.qq.com/relation/del_idol",
   array("format" => "json", "#name-1", "#fopenid-1"),
   "post"
  )
 );
 private $keysarr;
 function __construct(){
  if($_session["openid"]){
   $this->keysarr = array(
    "oauth_consumer_key" => appid,
    "access_token" => $_session['access_token'],
    "openid" => $_session["openid"]
   );
  }else{
   $this->keysarr = array(
    "oauth_consumer_key" => appid
   );
  }
 }
 public function qq_login(){
  //-------生成唯一随机串防csrf攻击
  $_session['state'] = md5(uniqid(rand(), true));
  $keysarr = array(
   "response_type" => "code",
   "client_id" => appid,
   "redirect_uri" => callback,
   "state" => $_session['state'],
   "scope" => scope
  );
  $login_url = self::get_auth_code_url.'?'.http_build_query($keysarr);
  header("location:$login_url");
 }
 public function qq_callback(){
  //--------验证state防止csrf攻击
  if($_get['state'] != $_session['state']){
   return false;
  }
  //-------请求参数列表
  $keysarr = array(
   "grant_type" => "authorization_code",
   "client_id" => appid,
   "redirect_uri" => callback,
   "client_secret" => appkey,
   "code" => $_get['code']
  );
  //------构造请求access_token的url
  $token_url = self::get_access_token_url.'?'.http_build_query($keysarr);
  $response = $this->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->error)){
    $this->showerror($msg->error, $msg->error_description);
   }
  }
  $params = array();
  parse_str($response, $params);
  $_session["access_token"]=$params["access_token"];
  $this->keysarr['access_token']=$params['access_token'];
  return $params["access_token"];
 }
 
 public function get_contents($url){
  if (ini_get("allow_url_fopen") == "1") {
   $response = file_get_contents($url);
  }else{
   $ch = curl_init();
   curl_setopt($ch, curlopt_ssl_verifypeer, false);
   curl_setopt($ch, curlopt_returntransfer, true);
   curl_setopt($ch, curlopt_url, $url);
   $response = curl_exec($ch);
   curl_close($ch);
  }
  if(empty($response)){
   return false;
  }
  return $response;
 }
 public function get_openid(){
  //-------请求参数列表
  $keysarr = array(
   "access_token" => $_session["access_token"]
  );
  $graph_url = self::get_openid_url.'?'.http_build_query($keysarr);
  $response = $this->get_contents($graph_url);
  //--------检测错误是否发生
  if(strpos($response, "callback") !== false){
   $lpos = strpos($response, "(");
   $rpos = strrpos($response, ")");
   $response = substr($response, $lpos + 1, $rpos - $lpos -1);
  }
  $user = json_decode($response);
  if(isset($user->error)){
   $this->showerror($user->error, $user->error_description);
  }
  //------记录openid
  $_session['openid']=$user->openid;
  $this->keysarr['openid']=$user->openid;
  return $user->openid;
 }
 
 /**
  * showerror
  * 显示错误信息
  * @param int $code 错误代码
  * @param string $description 描述信息(可选)
  */
 public function showerror($code, $description = '$'){
   echo "<meta charset=\"utf-8\">";
   echo "<h3>error:</h3>$code";
   echo "<h3>msg :</h3>$description";
   exit();
 }
 
 /**
  * _call
  * 魔术方法,做api调用转发
  * @param string $name 调用的方法名称
  * @param array $arg  参数列表数组
  * @since 5.0
  * @return array   返加调用结果数组
  */
 public function __call($name,$arg){
  //如果apimap不存在相应的api
  if(empty($this->apimap[$name])){
   $this->showerror("api调用名称错误","不存在的api: <span style='color:red;'>$name</span>");
  }
  //从apimap获取api相应参数
  $baseurl = $this->apimap[$name][0];
  $argslist = $this->apimap[$name][1];
  $method = isset($this->apimap[$name][2]) ? $this->apimap[$name][2] : "get";
  if(empty($arg)){
   $arg[0] = null;
  }
  $responsearr = json_decode($this->_applyapi($arg[0], $argslist, $baseurl, $method),true);
  //检查返回ret判断api是否成功调用
  if($responsearr['ret'] == 0){
   return $responsearr;
  }else{
   $this->showerror($responsearr['ret'], $responsearr['msg']);
  }
 }
 
 //调用相应api
 private function _applyapi($arr, $argslist, $baseurl, $method){
  $pre = "#";
  $keysarr = $this->keysarr;
  $optionarglist = array();//一些多项选填参数必选一的情形
  foreach($argslist as $key => $val){
   $tmpkey = $key;
   $tmpval = $val;
   if(!is_string($key)){
    $tmpkey = $val;
    if(strpos($val,$pre) === 0){
     $tmpval = $pre;
     $tmpkey = substr($tmpkey,1);
     if(preg_match("/-(\d$)/", $tmpkey, $res)){
      $tmpkey = str_replace($res[0], "", $tmpkey);
      $optionarglist[]= $tmpkey;
     }
    }else{
     $tmpval = null;
    }
   }
   //-----如果没有设置相应的参数
   if(!isset($arr[$tmpkey]) || $arr[$tmpkey] === ""){
    if($tmpval == $pre){
     continue;
    }else if($tmpval){//则使用默认的值
     $arr[$tmpkey] = $tmpval;
    }else{
     $this->showerror("api调用参数错误","未传入参数$tmpkey");
    }
   }
   $keysarr[$tmpkey] = $arr[$tmpkey];
  }
  //检查选填参数必填一的情形
  if(count($optionarglist)!=0){
   $n = 0;
   foreach($optionarglist as $val){
    if(in_array($val, array_keys($keysarr))){
     $n++;
    }
   }
   if(!$n){
    $str = implode(",",$optionarglist);
    $this->showerror("api调用参数错误",$str."必填一个");
   }
  }
  if($method == "post"){
   $response = $this->post($baseurl, $keysarr, 0);
  }else if($method == "get"){
   $baseurl=$baseurl.'?'.http_build_query($keysarr);
   $response = $this->get_contents($baseurl);
  }
  return $response;
 }
 
 public function post($url, $keysarr, $flag = 0){
  $ch = curl_init();
  if(! $flag) curl_setopt($ch, curlopt_ssl_verifypeer, false);
  curl_setopt($ch, curlopt_returntransfer, true);
  curl_setopt($ch, curlopt_post, true);
  curl_setopt($ch, curlopt_postfields, $keysarr);
  curl_setopt($ch, curlopt_url, $url);
  $ret = curl_exec($ch);
  curl_close($ch);
  return $ret;
 }
}

方法三,面向对象 使用腾讯给的sdk
使用方法:腾讯sdk,api写的很详细,不做赘述
地址:http://wiki.connect.qq.com/%e7%bd%91%e7%ab%99%e6%8e%a5%e5%85%a5%e6%a6%82%e8%bf%b0

这样就实现了qq快捷登录,其实很简单的,大家可以试一试。
还有什么不清楚的,可以看看官方介绍,更详细,

tips:如何在本地测试qq快速登录
方法:修改host配置文件
1. 打开c:\windows\system32\drivers\etc\host
2. 添加127.0.0.1    www.test.com
然后操作就可以了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

延伸 · 阅读

精彩推荐