前言:
php實現qq快速登錄,羅列了三種方法
方法一:面向過程,回調地址和首次觸發登錄寫到了一個方法頁面【因為有了if做判斷】,
方法二,三:面向對象
1.先調用登錄方法,向騰訊發送請求,
2.騰訊攜帶本網站唯一對應參數openid,accesstoken,返回到對應回調頁面,
3.回調頁面接受到騰訊的參數后,通過這個兩個參數,再發出對應的請求,如查詢用戶的數據。
4.騰訊做出對應的操作,如返回這個用戶的數據給你
即使你沒看懂,也沒關系,按照我下面的流程來,保證你可以實現。
前期準備:
使用人家騰訊的功能,總得和人家打招呼吧!
qq互聯首頁:http://connect.qq.com/
進入網址后,按如下操作來:
一.進入官網
二.申請創建【網站】應用
三.按要求填寫資料
注意網站地址:填寫你要設置快速登錄的網址,eg:http://www.test.com;
回調地址:填寫你發送qq快速登陸后,騰訊得給你信息,這個信息往此頁面接受。eg:http://www.test.com/accept_info.php
【詳細的申請填寫,請見官方提示,這里不做贅述】
四.申請成功后,完善信息
最終要求,獲得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
然后操作就可以了。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。