php教程

超轻量级php框架startmvc

PHP实现QQ快速登录的方法

更新时间:2020-03-11 19:21:10 作者:startmvc
前言: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>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.在调用方法中,代码:


$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\host 2. 添加127.0.0.1    www.test.com 然后操作就可以了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

PHP QQ 登录