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

出处至:脚本之家  http://www.jb51.net/article/93749.htm

时间: 2024-08-29 19:42:36

PHP实现QQ第三方登录的方法的相关文章

javaEE SSH框架 qq第三方登录及用户绑定

前几天刚申请好域名,下面实现网站的qq第三方登录的功能,javaEE的SSH框架.(一些细节问题没有处理,只是大体上实现) 一:首先说一下需求,第一次使用qq第三方登录的用户需要绑定已有的网站用户名,绑定成功后进入首页.以后再使用qq第三方登录就直接进入网站首页. 二:要想使用qq第三方首先需要申请应用(需要有自己的域名) (1)登录qq互联网站申请应用,http://connect.qq.com/ (2)创建应用 (3)创建好之后还是可以修改的,这里回调地址我用的是域名+back.jsp界面(

QQ第三方登录

QQ第三方登录 在Android应用程序的开发过程中,很多时候需要加入用户登录/注册模块.除了自己动手设计登录界面并实现相应功能外,现在还可以借助百度.腾讯等开发者平台提供的第三方账号登录模块.最近研究了友盟的社会化分享组件,对其提供的SDK中第三方登录的QQ模块进行了测试.本篇文章先对友盟用户注册.SDK下载及案例的下载做一个简单的介绍,然后针对测试程序的过程及代码进行详细的描述. 顺便提一点,进入友盟的主页及SDK下载页面之后,会发现其支持Android.IOS等多个环境下的应用程序开发,感

Android应用之最新版本SDKV2.4实现QQ第三方登录

为什么要写这篇博客呢?因为,我在做这个第三方登录的时候,找了很多资料,发现要么就是过时了,要么就是说的很不清楚,很罗嗦,而且很多都是一些小 demo,不是什么实例,甚至连腾讯官方的文档都有这个问题,文档中很多地方用的不是最新的sdk写的示例,用最新版本的sdk发现根本没法达到预期的效 果,很多api已经发生了变化,demo还是用的原来的api中的方法,最坑爹是demo下载下来还要一个支持的库文件,但是sdk中又没有提供.. 自己跌跌撞撞,查找资料,整合,弄了几个小时,终于把它给整出来了,用在了开

Android应用之——最新版本SDK V2.4实现QQ第三方登录

为什么要写这篇博客呢?因为,我在做这个第三方登录的时候,找了很多资料,发现要么就是过时了,要么就是说的很不清楚,很罗嗦,而且很多都是一些小demo,不是什么实例,甚至连腾讯官方的文档都有这个问题,文档中很多地方用的不是最新的sdk写的示例,用最新版本的sdk发现根本没法达到预期的效果,很多api已经发生了变化,demo还是用的原来的api中的方法,最坑爹是demo下载下来还要一个支持的库文件,但是sdk中又没有提供.. 自己跌跌撞撞,查找资料,整合,弄了几个小时,终于把它给整出来了,用在了开发的

Android 实现QQ第三方登录

在项目中需要实现QQ第三方登录,经过一番努力算是写出来了,现在总结以下,以防以后遗忘,能帮到其他童鞋就更好了. 首先肯定是去下载SDK和DEMO http://wiki.open.qq.com/wiki/mobile/SDK下载 本文是我自己整合后的简单DEMO. 先看下效果图吧 小码哥Html5教程,免费随你看 [点击进入] 24小时阅读30000+,48小时视频下载50000+ H5,JS,CSS,0基础学完独立开发网站/APP! 查 看 小码哥Html5教程,免费随你看 [点击进入] 24

javaEE SSH框架 qq第三方登录及用户绑定(java sdk版)

之前有位朋友用js sdk实现了 SSH框架下的qq第三方登录功能,但是我发现使用js sdk 有些无法克服的安全问题,所以我改用java sdk来实现这个功能! 如图,使用java sdk时,回调地址应设置为一个.action链接.(注意!修改回调地址的话,官方不会及时给你审核通过,有的人修改回调地址后一年 官方都没给他审核通过,这意味着[修改回调地址不如 要重新申请一个域名!重新申请一次网站接入]) 使用官方给定的Sdk4J.jar时 控制台会打印许多log信息,这严重影响项目的运行效率,所

使用QQ第三方登录时,手机应用和网站应用对同一个QQ号,获取到的openid不一样

使用QQ第三方登录时,手机应用和网站应用对同一个QQ号,获取到的openid不一样openid生成是根据应用的appid和QQ号的一些信息加密生成,对于一个appid和QQ号来说,openid是唯一的手机应用和网站应用使用的appid不是同一个,所以,获取到的openid也不会相同 那么问题来了同一个QQ,通过手机端第三方登录进去,和通过网站登录进去,因为openid不一样,会生成两个用户 解决方法: 给[email protected]发送邮件,内容格式: 第三方登录,web端返回的openi

利用JS_SDK实现QQ第三方登录

前言 现如今,第三方登录已成为大部分网站必备的一项基础技能,引入时髦的第三方登录不仅能帮你吸引更多的用户,也让你的网站可以充分利用其他大型网站的用户资源.本次教程将让你的网站最快捷便利地引入QQ登录. QQ第三方登录目前提供了JS SDK功能,这也是目前最简单直接的接入QQ互联的方式,没有之一.下面我将通过简单的几步轻松地让你的网站接入QQ登录. 准备工作 在正式接入之前你需要了解以下名词的含义: 1. appid :应用的唯一标识.在OAuth2.0认证过程中,appid的值即为oauth_c

iOS微信实现第三方登录的方法

这篇文章主要介绍了iOS微信第三方登录实现的全过程,一步一步告诉大家iOS微信实现第三方登录的方法,感兴趣的小伙伴们可以参考一下 一.接入微信第三方登录准备工作.移动应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统.在进行微信OAuth2.0授权登录接入之前,在微信开放平台注册开发者帐号,并拥有一个已审核通过的移动应用,并获得相应的AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程.(注意)1.下载iOS微信SDK.下载地址 2.将SDK放到