CI框架 QQ接口(第三方登陸接口PHP版)php
本帖內容較多,大部分都是源碼,要修改的地方只有一個,其餘只要複製過去,就能夠完美運行。本帖主要針對CI框架,不用下載SDK,按我下面的步驟,建文件,複製代碼就能夠了。10分鐘不要,接口就可完成。
第一步:申請APP ID,APP KEY,申請地址:http://connect.opensns.qq.com/
驗證經過後:會獲得APP ID,APP KEY。這是你用個文件把這些信息保持下來,省得用的時候有要上網去查,記錄在本地記事本里,方便,用的時候打開就能夠。以下:
APP ID:101091331
APP KEY:7cb032049f2c900fea509424e614a979
回調地址:http://test.com
第二步:若是你的系統沒有安裝curl,請先安裝curl。
怎麼知道本地系統是否安裝了curl呢,方法以下:
1.在web服務器目錄( Ubuntu下的一般爲 /var/www )新建crul.php文件
2.編輯文件,鍵入下面一行代碼:
<?php phpinfo(); ?>
3.保存文件
4.打開瀏覽器,瀏覽該網頁。(例如:http://localhost/curl.php)
5.搜索"curl",若是沒搜到就證實沒安裝curl。
下面是安裝方法:
打開終端,輸入下面的命令:
sudo apt-get install curl libcurl3 libcurl3-dev php5-curl
再重啓apache:
sudo /etc/init.d/apache2 restart
這樣curl就安裝好了,打開你剛纔的那個頁面,搜一下curl,就能夠看到了curl了,這表示已經安裝成功,很簡單吧。
若是仍是沒有,編輯你的php.ini文件,個人phpini.php文件在/etc/php5/apache2/php.ini,估計你的也差很少是在這個位置,去找找看,找到後,打開這個文件,在最後加上一行:
extension=curl.so
保存文件後重啓Apache服務器,再打開頁面,就會出現curl了。
第三步:代碼
注:騰訊提供了SDK,能夠在官網下載:下載地址:http://wiki.connect.qq.com/sdk%E4%B8%8B%E8%BD%BD,若是不是CI框架,估計下載下來就能夠用了,CI框架調用規則不一樣,因此要作修改,若是是CI框架下開發QQ登陸接口,就不用下載SDK了,用我下面的代碼,下面正式上代碼,完整的代碼。
代碼步驟:
1.打開application/config/constants.php文件
寫入以下代碼:
/*qq登錄*/
define('GET_AUTH_CODE_URL', "https://graph.qq.com/oauth2.0/authorize");
define('GET_ACCESS_TOKEN_URL' , "https://graph.qq.com/oauth2.0/token");
define('GET_OPENID_URL' , "https://graph.qq.com/oauth2.0/me");
保存
2.打開application文件夾,在application下新建一個文件夾isetting,在isetting下建一個qq_setting.php文件,
打開qq_setting.php文件,輸入以下代碼:git
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* @qq互聯配置信息
* 默認開啓get_user_info模塊
* **/
$config['inc_info'] = array(
array (
'appid' => '101091331',
'appkey' => '7cb032049f2c900fea509424e614a979',
'callback' => 'http://test.com'
),
array (
'get_user_info' => '1',
'add_topic' => '0',
'add_one_blog' => '0',
'add_album' => '0',
'upload_pic' => '0',
'list_album' => '0',
'add_share' => '0',
'check_page_fans' => '0',
'add_t' => '0',
'add_pic_t' => '0',
'del_t' => '0',
'get_repost_list' => '0',
'get_info' => '0',
'get_other_info' => '0',
'get_fanslist' => '0',
'get_idollist' => '0',
'add_idol' => '0',
'del_idol' => '0',
'get_tenpay_addr' => '0',
)
);
保存
說明:你須要把appid,appkey對應的鍵值修改爲你剛剛申請的appid,appkey值,callback爲回調地址(所謂回調地址就是登陸成功後,返回到哪一個頁面),callback的值寫你申請的時候作驗證的那個地址。
3.打開application下的libraries文件,新建一個文件夾tencent,在tencent裏面新建一個文件oauth.php,打開這個文件,複製下面的代碼進去:
<?php
class Oauth
{
/**
* combineURL
* 拼接url
* @param string $baseURL 基於的url
* @param array $keysArr 參數列表數組
* @return string 返回拼接的url
*/
private $APIMap;
public function __construct() {
/*如下部分爲獲取第三方qq登錄資料*/
//初始化APIMap
/*
* 加#表示非必須,無則不傳入url(url中不會出現該參數), "key" => "val" 表示key若是沒有定義則使用默認值val
* 規則 array( baseUrl, argListArr, method)
*/
$this->APIMap = array(
/* qzone */
"add_blog" => array(
"https://graph.qq.com/blog/add_one_blog",
array("title", "format" => "json", "content" => null),
"POST"
),
"add_topic" => array(
"https://graph.qq.com/shuoshuo/add_topic",
array("richtype","richval","con","#lbs_nm","#lbs_x","#lbs_y","format" => "json", "#third_source"),
"POST"
),
"get_user_info" => array(
"https://graph.qq.com/user/get_user_info",
array("format" => "json"),
"GET"
),
"add_one_blog" => array(
"https://graph.qq.com/blog/add_one_blog",
array("title", "content", "format" => "json"),
"GET"
),
"add_album" => array(
"https://graph.qq.com/photo/add_album",
array("albumname", "#albumdesc", "#priv", "format" => "json"),
"POST"
),
"upload_pic" => array(
"https://graph.qq.com/photo/upload_pic",
array("picture", "#photodesc", "#title", "#albumid", "#mobile", "#x", "#y", "#needfeed", "#successnum", "#picnum", "format" => "json"),
"POST"
),
"list_album" => array(
"https://graph.qq.com/photo/list_album",
array("format" => "json")
),
"add_share" => array(
"https://graph.qq.com/share/add_share",
array("title", "url", "#comment","#summary","#images","format" => "json","#type","#playurl","#nswb","site","fromurl"),
"POST"
),
"check_page_fans" => array(
"https://graph.qq.com/user/check_page_fans",
array("page_id" => "314416946","format" => "json")
),
/* wblog */
"add_t" => array(
"https://graph.qq.com/t/add_t",
array("format" => "json", "content","#clientip","#longitude","#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", "fopenid")
),
"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"
),
/* pay */
"get_tenpay_addr" => array(
"https://graph.qq.com/cft_info/get_tenpay_addr",
array("ver" => 1,"limit" => 5,"offset" => 0,"format" => "json")
)
);
}
//登錄
public function check_login()
{
if(isset($_SESSION['qq']['state']) && $_GET['state'] && ($_SESSION['qq']['state'] == $_GET['state']))
{
return 'true';
}
else
{
return 'false';
}
}
public function qq_login()
{
$CI = &get_instance();
$CI->config->load('isetting/qq_setting');
$setting = $CI->config->item('inc_info');
$appid = $setting[0]['appid'];
$callback = $setting[0]['callback'];
$scope = '';
foreach ($setting[1] as $key=>$val)
{
if($val === '1')
{
$scope .= $key . ',';
}
}
$scope = trim(rtrim($scope,','));
//-------生成惟一隨機串防CSRF攻擊
$state = md5(uniqid(rand(), TRUE));
$_SESSION['qq']['state'] = $state;
//-------構造請求參數列表
$keysArr = array(
"response_type" => "code",
"client_id" => $appid,
"redirect_uri" => $callback,
"state" => $state,
"scope" => $scope
);
$login_url = $this->combineURL(GET_AUTH_CODE_URL, $keysArr);
header("Location:$login_url");
}
//callback回調方法
public function qq_callback()
{
$CI = &get_instance();
$CI->config->load('isetting/qq_setting');
$setting = $CI->config->item('inc_info');
$state = $_SESSION['qq']['state'];
//--------驗證state防止CSRF攻擊
if($_GET['state'] != $state){
echo "<script>alert('QQ第三方登錄失敗');</script>";
redirect('/login','location',301);
}
//-------請求參數列表
$keysArr = array(
"grant_type" => "authorization_code",
"client_id" => $setting[0]['appid'],
"redirect_uri" => $setting[0]['callback'],
"client_secret" => $setting[0]['appkey'],
"code" => $_GET['code']
);
//------構造請求access_token的url
$token_url = $this->combineURL(GET_ACCESS_TOKEN_URL, $keysArr);
$response = $this->get_contents($token_url);
$params = array();
parse_str($response, $params);
$_SESSION['qq']['access_token'] = $params["access_token"];
$access_token = $params["access_token"];
$openid= $this->get_openid();
//進入主頁
//獲取用戶信息
$_data = $this->qq_get_user($access_token,$openid);
redirect('/','location',301);
}
//註銷
public function qq_logout()
{
}
public function combineURL($baseURL,$keysArr){
$combined = $baseURL."?";
$valueArr = array();
foreach($keysArr as $key => $val){
$valueArr[] = "$key=$val";
}
$keyStr = implode("&",$valueArr);
$combined .= ($keyStr);
return $combined;
}
/**
* get_contents
* 服務器經過get請求得到內容
* @param string $url 請求的url,拼接後的
* @return string 請求返回的內容
*/
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)){
echo "<script>alert('QQ第三方登錄失敗');</script>";
redirect('/login','location',301);
}
return $response;
}
public function get_openid()
{
//-------請求參數列表
$keysArr = array(
"access_token" => $_SESSION['qq']['access_token']
);
$graph_url = $this->combineURL(GET_OPENID_URL, $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);
//------記錄openid
$_SESSION['qq']['openid'] = $user->openid;
return $user->openid;
}
/**
* _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])){
echo "<script>alert('獲取資料出錯');</script>";
redirect('/login','location',301);
}
//從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;
}
//對於get_tenpay_addr,特殊處理,php json_decode對\xA312此類字符支持很差
if($name != "get_tenpay_addr"){
$response = json_decode($this->_applyAPI($arg[0], $argsList, $baseUrl, $method));
$responseArr = $this->objToArr($response);
}else{
$responseArr = $this->simple_json_parser($this->_applyAPI($arg[0], $argsList, $baseUrl, $method));
}
//檢查返回ret判斷api是否成功調用
if($responseArr['ret'] == 0){
return $responseArr;
}else{
echo "<script>alert('第三方登錄失敗')</script>";
redirect('/','location',301);
}
}
//調用相應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[$res[1]][] = $tmpKey;
}
}else{
$tmpVal = null;
}
}
//-----若是沒有設置相應的參數
if(!isset($arr[$tmpKey]) || $arr[$tmpKey] === ""){
if($tmpVal == $pre){//則使用默認的值
continue;
}else if($tmpVal){
$arr[$tmpKey] = $tmpVal;
}else{
if($v = $_FILES[$tmpKey]){
$filename = dirname($v['tmp_name'])."/".$v['name'];
move_uploaded_file($v['tmp_name'], $filename);
$arr[$tmpKey] = "@$filename";
}else{
$this->error->showError("api調用參數錯誤","未傳入參數$tmpKey");
}
}
}
$keysArr[$tmpKey] = $arr[$tmpKey];
}
//檢查選填參數必填一的情形
foreach($optionArgList as $val){
$n = 0;
foreach($val as $v){
if(in_array($v, array_keys($keysArr))){
$n ++;
}
}
if(! $n){
$str = implode(",",$val);
$this->error->showError("api調用參數錯誤",$str."必填一個");
}
}
if($method == "POST"){
if($baseUrl == "https://graph.qq.com/blog/add_one_blog") $response = $this->urlUtils->post($baseUrl, $keysArr, 1);
else $response = $this->urlUtils->post($baseUrl, $keysArr, 0);
}else if($method == "GET"){
$response = $this->urlUtils->get($baseUrl, $keysArr);
}
return $response;
}
//php 對象到數組轉換
private function objToArr($obj){
if(!is_object($obj) && !is_array($obj)) {
return $obj;
}
$arr = array();
foreach($obj as $k => $v){
$arr[$k] = $this->objToArr($v);
}
return $arr;
}
//簡單實現json到php數組轉換功能
private function simple_json_parser($json){
$json = str_replace("{","",str_replace("}","", $json));
$jsonValue = explode(",", $json);
$arr = array();
foreach($jsonValue as $v){
$jValue = explode(":", $v);
$arr[str_replace('"',"", $jValue[0])] = (str_replace('"', "", $jValue[1]));
}
return $arr;
}
}
保存
說明:這段代碼複製不過就行,不用作任何改動。這個是最核心的代碼,代碼比較多,可是功能代碼就這些了,想一想,在本身的網站上,別人用qq賬號就能夠登陸了,都不用註冊,多方便啊,是吧,這樣一想這些代碼也不算多了。
4.建控制器。打開application下的controllers文件夾,在controllers下新建一個文件qq.php,打開qq.php,複製下面代碼:web
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
* @ qq登錄 註銷 消息獲取等
* @author
*/
class QQ extends CI_Controller
{
public function __construct() {
parent::__construct();
session_start();
$this->load->helper('url');
//error_reporting(0);
/*qq登錄*/
$this->load->library('tencent/oauth','oauth');
}
public function index()
{
//驗證是登錄仍是回調
if($this->oauth->check_login() === 'false')
{
$this->oauth->qq_login();
}
else
{
$this->oauth->qq_callback();
}
}
}
保存
說明:這段代碼不用作修改。
5.放置登陸按鈕,點擊用QQ賬號登陸按鈕,跳轉到QQ登陸頁面登陸。
在你的登陸頁面放按鈕的位置,寫入:
<div><a href="/qq"><img src="http://images.cnblogs.com/qq_login.png" width="110" /></a></div>
保存
說明:樣式你可本身調整,圖片按鈕能夠從官網下載,地址:http://wiki.connect.qq.com/%E8%A7%86%E8%A7%89%E7%B4%A0%E6%9D%90%E4%B8%8B%E8%BD%BD#2.QQ.E7.99.BB.E5.BD.95.E6.A1.86.E6.A0.87.E5.87.86.E6.A0.B7.E5.BC.8F
到這裏,QQ第三方登陸接口就OK了,你打開你的登陸頁面,點擊QQ登陸的圖片按鈕,它會轉到QQ登陸頁面登陸,若是要上線,要用到別的功能,可在這幾個文件上填代碼就好了。
申明:
本帖僅供學習參考,不涉及任何商業範圍,若有冒犯,敬請原諒!
若有不對的地方,或者能夠改良的地方,請回復指點,受教受教!apache