前言:php
PHP實現QQ快速登陸,羅列了三種方法git
方法一:面向過程,回調地址和首次觸發登陸寫到了一個方法頁面【由於有了if作判斷】,json
方法二,三:面向對象api
1.先調用登陸方法,向騰訊發送請求,
2.騰訊攜帶本網站惟一對應參數OPENID,ACCESSTOKEN,返回到對應回調頁面,
3.回調頁面接受到騰訊的參數後,經過這個兩個參數,再發出對應的請求,如查詢用戶的數據。
4.騰訊作出對應的操做,如返回這個用戶的數據給你數組
即便你沒看懂,也不要緊,按照我下面的流程來,保證你能夠實現。session
前期準備:app
使用人家騰訊的功能,總得和人家打招呼吧!curl
QQ互聯首頁:http://connect.qq.com/post
進入網址後,按以下操做來:測試
一.進入官網
二.申請建立【網站】應用
三.按要求填寫資料
注意網站地址:填寫你要設置快速登陸的網址,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爲返回的登陸信息
代碼:
----------------------------------------------------------------------------------------------------------------------------------------------------------
//應用的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 >openid,</span><span >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.在調用方法中,代碼:
$qq_login
=
new
\Component\QQ_LoginAction();
//引入此類文件便可
$qq_login
->qq_login();
3.在回調頁面中,代碼:
$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】
----------------------------------------------------------------------------------------------------------------------
<?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\host2. 添加127.0.0.1 www.test.com而後操做就能夠了。