PHP實作QQ快速登入的方法
前言:
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為傳回的登入資訊
//应用的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 id="error">error:</h3>" . $msg->error; echo "<h3 id="msg-nbsp">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 id="error">error:</h3>" . $user->error; echo "<h3 id="msg-nbsp">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.在呼叫方法中,代碼:
$qq_login = new \Component\QQ_LoginAction(); //引入此类文件即可 $qq_login->qq_login(); //调用登录方法,向腾讯发出快速登录请求
$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 id="error">error:</h3>$code"; echo "<h3 id="msg-nbsp">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:WindowsSystem32driversetchost
2. 新增127.0.0.1 www .test.com

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

在PHP中,應使用password_hash和password_verify函數實現安全的密碼哈希處理,不應使用MD5或SHA1。1)password_hash生成包含鹽值的哈希,增強安全性。 2)password_verify驗證密碼,通過比較哈希值確保安全。 3)MD5和SHA1易受攻擊且缺乏鹽值,不適合現代密碼安全。

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

PHP類型提示提升代碼質量和可讀性。 1)標量類型提示:自PHP7.0起,允許在函數參數中指定基本數據類型,如int、float等。 2)返回類型提示:確保函數返回值類型的一致性。 3)聯合類型提示:自PHP8.0起,允許在函數參數或返回值中指定多個類型。 4)可空類型提示:允許包含null值,處理可能返回空值的函數。

PHP和Python各有優劣,選擇取決於項目需求和個人偏好。 1.PHP適合快速開發和維護大型Web應用。 2.Python在數據科學和機器學習領域佔據主導地位。

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。
