PHP實(shí)現(xiàn)QQ快速登錄的方法
前言:
PHP實(shí)現(xiàn)QQ快速登錄,羅列了三種方法
方法一:面向過(guò)程,回調(diào)地址和首次觸發(fā)登錄寫到了一個(gè)方法頁(yè)面【因?yàn)橛辛薸f做判斷】,
方法二,三:面向?qū)ο?br />
1.先調(diào)用登錄方法,向騰訊發(fā)送請(qǐng)求,
2.騰訊攜帶本網(wǎng)站唯一對(duì)應(yīng)參數(shù)OPENID,ACCESSTOKEN,返回到對(duì)應(yīng)回調(diào)頁(yè)面,
3.回調(diào)頁(yè)面接受到騰訊的參數(shù)后,通過(guò)這個(gè)兩個(gè)參數(shù),再發(fā)出對(duì)應(yīng)的請(qǐng)求,如查詢用戶的數(shù)據(jù)。
4.騰訊做出對(duì)應(yīng)的操作,如返回這個(gè)用戶的數(shù)據(jù)給你
即使你沒(méi)看懂,也沒(méi)關(guān)系,按照我下面的流程來(lái),保證你可以實(shí)現(xiàn)。
前期準(zhǔn)備:
使用人家騰訊的功能,總得和人家打招呼吧!
QQ互聯(lián)首頁(yè):http://connect.qq.com/
進(jìn)入網(wǎng)址后,按如下操作來(lái):
一.進(jìn)入官網(wǎng)

二.申請(qǐng)創(chuàng)建【網(wǎng)站】應(yīng)用

三.按要求填寫資料
注意網(wǎng)站地址:填寫你要設(shè)置快速登錄的網(wǎng)址,eg:http://www.test.com;
回調(diào)地址:填寫你發(fā)送QQ快速登陸后,騰訊得給你信息,這個(gè)信息往此頁(yè)面接受。eg:http://www.test.com/accept_info.php
【詳細(xì)的申請(qǐng)?zhí)顚懀?qǐng)見(jiàn)官方提示,這里不做贅述】

四.申請(qǐng)成功后,完善信息

最終要求,獲得APP_ID ,APP_KEY
五.代碼部分:
在你對(duì)應(yīng)的PHP文件內(nèi)寫入,如下
方法一,面向過(guò)程法
使用方法:配置$app_id,$app_secret,$my_url后,其他原封復(fù)制即可,$user_data為返回的登錄信息
代碼:
//應(yīng)用的APPID
$app_id = "你的APPID";
//應(yīng)用的APPKEY
$app_secret = "你的APPKEY";
//【成功授權(quán)】后的回調(diào)地址,即此地址在騰訊的信息中有儲(chǔ)存
$my_url = "你的回調(diào)網(wǎng)址";
//Step1:獲取Authorization Code
session_start();
$code = $_REQUEST["code"];//存放Authorization Code
if(empty($code))
{
//state參數(shù)用于防止CSRF攻擊,成功授權(quán)后回調(diào)時(shí)會(huì)原樣帶回
$_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:通過(guò)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)//如果登錄用戶臨時(shí)改變主意取消了,返回true!==false,否則執(zhí)行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來(lái)獲取用戶的OpenID
$params = array();
parse_str($response, $params);//把傳回來(lái)的數(shù)據(jù)參數(shù)變量化
$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);//存放返回的數(shù)據(jù) 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來(lái)獲取所接受的用戶信息。</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.");
}
方法二,面向?qū)ο?使用類QQ_LoginAction.class
使用方法:
1.在QQ_LoginAction.class中正確配置 APPID,APPKEY CALLBACK(回調(diào)網(wǎng)址)
2.在調(diào)用方法中,代碼:
$qq_login = new \Component\QQ_LoginAction(); //引入此類文件即可 $qq_login->qq_login(); //調(diào)用登錄方法,向騰訊發(fā)出快速登錄請(qǐng)求
3.在回調(diào)頁(yè)面中,代碼:
$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()為獲得該用戶的信息,其他操作方法見(jiàn)API文檔
4.$user_data即為返回的用戶數(shù)據(jù)。
5.QQ_LoginAction.class.php 文件代碼:【用的ThinkPHP3.2】
<?php
namespace Component;
session_start();
define('APPID','XXXX'); //appid
define('APPKEY','XXXX'); //appkey
define('CALLBACK','XXXX'); //回調(diào)地址
define('SCOPE','get_user_info,list_album,add_album,upload_pic,add_topic,add_weibo'); //授權(quán)接口列表
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( //發(fā)布一條普通微博
"https://graph.qq.com/t/add_t",
array("format" => "json", "content","#clientip","#longitude","#latitude","#compatibleflag"),
"POST"
),
"add_pic_t" => array( //發(fā)布一條圖片微博
"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( //獲取單條微博的轉(zhuǎn)發(fā)或點(diǎn)評(píng)列表
"https://graph.qq.com/t/get_repost_list",
array("flag", "rootid", "pageflag", "pagetime", "reqnum", "twitterid", "format" => "json")
),
"get_info" => array( //獲取當(dāng)前用戶資料
"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", //我的微博收聽(tīng)列表
array("format" => "json", "reqnum", "startindex", "#mode", "#install")
),
"add_idol" => array(
"https://graph.qq.com/relation/add_idol", //微博收聽(tīng)某用戶
array("format" => "json", "#name-1", "#fopenids-1"),
"POST"
),
"del_idol" => array( //微博取消收聽(tīng)某用戶
"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(){
//-------生成唯一隨機(jī)串防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(){
//--------驗(yàn)證state防止CSRF攻擊
if($_GET['state'] != $_SESSION['state']){
return false;
}
//-------請(qǐng)求參數(shù)列表
$keysArr = array(
"grant_type" => "authorization_code",
"client_id" => APPID,
"redirect_uri" => CALLBACK,
"client_secret" => APPKEY,
"code" => $_GET['code']
);
//------構(gòu)造請(qǐng)求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(){
//-------請(qǐng)求參數(shù)列表
$keysArr = array(
"access_token" => $_SESSION["access_token"]
);
$graph_url = self::GET_OPENID_URL.'?'.http_build_query($keysArr);
$response = $this->get_contents($graph_url);
//--------檢測(cè)錯(cuò)誤是否發(fā)生
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
* 顯示錯(cuò)誤信息
* @param int $code 錯(cuò)誤代碼
* @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
* 魔術(shù)方法,做api調(diào)用轉(zhuǎn)發(fā)
* @param string $name 調(diào)用的方法名稱
* @param array $arg 參數(shù)列表數(shù)組
* @since 5.0
* @return array 返加調(diào)用結(jié)果數(shù)組
*/
public function __call($name,$arg){
//如果APIMap不存在相應(yīng)的api
if(empty($this->APIMap[$name])){
$this->showError("api調(diào)用名稱錯(cuò)誤","不存在的API: <span style='color:red;'>$name</span>");
}
//從APIMap獲取api相應(yīng)參數(shù)
$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是否成功調(diào)用
if($responseArr['ret'] == 0){
return $responseArr;
}else{
$this->showError($responseArr['ret'], $responseArr['msg']);
}
}
//調(diào)用相應(yīng)api
private function _applyAPI($arr, $argsList, $baseUrl, $method){
$pre = "#";
$keysArr = $this->keysArr;
$optionArgList = array();//一些多項(xiàng)選填參數(shù)必選一的情形
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;
}
}
//-----如果沒(méi)有設(shè)置相應(yīng)的參數(shù)
if(!isset($arr[$tmpKey]) || $arr[$tmpKey] === ""){
if($tmpVal == $pre){
continue;
}else if($tmpVal){//則使用默認(rèn)的值
$arr[$tmpKey] = $tmpVal;
}else{
$this->showError("api調(diào)用參數(shù)錯(cuò)誤","未傳入?yún)?shù)$tmpKey");
}
}
$keysArr[$tmpKey] = $arr[$tmpKey];
}
//檢查選填參數(shù)必填一的情形
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調(diào)用參數(shù)錯(cuò)誤",$str."必填一個(gè)");
}
}
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;
}
}
方法三,面向?qū)ο?使用騰訊給的SDK
使用方法:騰訊SDK,API寫的很詳細(xì),不做贅述
地址:http://wiki.connect.qq.com/%E7%BD%91%E7%AB%99%E6%8E%A5%E5%85%A5%E6%A6%82%E8%BF%B0
這樣就實(shí)現(xiàn)了QQ快捷登錄,其實(shí)很簡(jiǎn)單的,大家可以試一試。
還有什么不清楚的,可以看看官方介紹,更詳細(xì),
Tips:如何在本地測(cè)試QQ快速登錄
方法:修改HOST配置文件
1. 打開(kāi)C:\Windows\System32\drivers\etc\host
2. 添加127.0.0.1 www.test.com
然后操作就可以了。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- PHP版QQ互聯(lián)OAuth示例代碼分享
- QQ登錄 PHP OAuth示例代碼
- PHP第三方登錄—QQ登錄實(shí)現(xiàn)方法
- thinkPHP5項(xiàng)目中實(shí)現(xiàn)QQ第三方登錄功能
- PHP實(shí)現(xiàn)QQ登錄實(shí)例代碼
- PHP模擬QQ登錄的方法
- PHP實(shí)現(xiàn)QQ登錄的開(kāi)原理和實(shí)現(xiàn)過(guò)程
- PHP+jquery+CSS制作頭像登錄窗(仿QQ登陸)
- 淺談PHP接入(第三方登錄)QQ登錄 OAuth2.0 過(guò)程中遇到的坑
- PHP調(diào)用QQ互聯(lián)接口實(shí)現(xiàn)QQ登錄網(wǎng)站功能示例
相關(guān)文章
php驗(yàn)證碼實(shí)現(xiàn)代碼(3種)
這篇文章主要介紹了php驗(yàn)證碼實(shí)現(xiàn)代碼,純數(shù)字驗(yàn)證碼,數(shù)字加英文驗(yàn)證碼還有一種漢字驗(yàn)證碼,感興趣的小伙伴們可以參考一下2015-09-09
自編函數(shù)解決pathinfo()函數(shù)處理中文問(wèn)題
本文主要介紹了小編在使用pathinfo()函數(shù)處理中文文件名時(shí)遇到的一個(gè)小BUG的處理方式,有相同問(wèn)題的童鞋們可以參考下2014-11-11
命令行執(zhí)行php腳本中的$argv和$argc配置方法
這篇文章主要介紹了命令行執(zhí)行php腳本 中$argv和$argc的方法,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2018-01-01
thinkPHP+phpexcel實(shí)現(xiàn)excel報(bào)表輸出功能示例
這篇文章主要介紹了thinkPHP+phpexcel實(shí)現(xiàn)excel報(bào)表輸出功能,結(jié)合具體實(shí)例形式分析了thinkPHP整合PHPExcel實(shí)現(xiàn)針對(duì)Excel文件相關(guān)操作技巧,需要的朋友可以參考下2017-06-06
用php守護(hù)另一個(gè)php進(jìn)程的例子
這篇文章主要介紹了用php守護(hù)另一個(gè)php進(jìn)程的例子,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-02-02
ThinkPHP采用GET方式獲取中文參數(shù)查詢無(wú)結(jié)果的解決方法
這篇文章主要介紹了ThinkPHP采用GET方式獲取中文參數(shù)查詢無(wú)結(jié)果的解決方法,需要的朋友可以參考下2014-06-06
Yii列表定義與使用分頁(yè)方法小結(jié)(3種方法)
這篇文章主要介紹了Yii列表定義與使用分頁(yè)方法,總結(jié)分析了3種方法供大家參考,涉及Yii針對(duì)數(shù)據(jù)庫(kù)的查詢、分頁(yè)計(jì)算及相關(guān)類與方法的使用技巧,需要的朋友可以參考下2016-07-07

