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
然后操作就可以了。

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

(0)

相关推荐

  • PHP编写登录验证码功能 附调用方法

    本文实例为大家分享了一个PHP写的登录验证码功能,供大家参考,具体内容如下 ShowKey.php <?php session_start(); //设置COOKIE或Session function esetcookie($name,$str,$life=0){ //本函数将字符串 str 全部变小写字符串使验证码输入不区分大小写----在提交表单进行session比较同样需要次函数转化 $_SESSION[$name]=strtolower($str); } //获取随机字符 此函数区分字符

  • php+MySQL实现登录时验证登录名和密码是否正确

    直入主题,先看php校验登录名和密码是否正确的代码: <?php $servername = "服务器名"; $username = "账户名"; $password = "密码"; $dbname = "数据库名"; ?> <?php // Session需要先启动. session_start(); //判断uname和pwd是否赋值 if(isset($_POST['uname']) &&

  • PHP版微信第三方实现一键登录及获取用户信息的方法

    本文实例讲述了PHP版微信第三方实现一键登录及获取用户信息的方法.分享给大家供大家参考,具体如下: 注意,要使用微信在第三方网页登录是需要"服务号"才可以哦,所以必须到官方申请. 一开始你需要进入微信公众平台开启开发模式,并且填写oauth2的回调地址,地址填写你项目的域名就可以了.比如:www.baidu.com或zhidao.baidu.com.如果你的项目在二级域名就写二级域名 前端url授权地址,在url中填写appid与你项目中方法中的oauth的地址,具体在下面的代码中可以

  • PHP登录(ajax提交数据和后台校验)实例分享

    1.前台ajax数据提交 <form id="login_form" action="" method="POST"> <div class="login_frame" style="position:relative";> <div class="login_gl" style="margin-top:35px;"> <sp

  • PHP如何通过AJAX方式实现登录功能

    本文实例讲述了Ajax+PHP+MySQL登陆示例.分享给大家供大家参考.具体如下: 运行效果截图如下: 具体代码如下: 1 login.php 登录界面中,javascript脚本用ajax方式异步请求dologin.php,dologin.php负责用户信息验证(包括验证码,php生成验证码可以自行搜索).登录界面的代码如下: <?php session_start();?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Tran

  • php有效防止同一用户多次登录

    [问题描述]:同一用户在同一时间多次登录如果不能检测出来,是危险的.因为,你无法知道是否有其他用户在登录你的账户.如何禁止同一用户多次登录呢? [解决方案] (1) 每次登录,身份认证成功后,重新产生一个session_id. session_regenerate_id(); session_register ("username") ; (2) 在用户数据库中开一个sessionid字段,重新产生session_id后,都更新该字段. $sessionid = session_id(

  • php bootstrap实现简单登录

    本文实例为大家分享了php bootstrap实现简单登录的方法,供大家参考,具体内容如下 所有文件 记住是获取name键值对 from 里面 action就是你的动作 signin.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" con

  • 基于PHP实现用户注册登录功能

    本文介绍的是基于PHP实现用户注册登录功能,本项目分为四部分内容:1前端页面制作,2验证码制作,3实现注册登陆,4功能完善.具体情况可以往下看. 验证码制作 一.实验简介 本次实验将会带领大家使用面向对象的思想封装一个验证码类.并在注册和登陆界面展示使用.通过本次实验的学习,你将会领悟到 PHP 的 OOP 思想,以及 GD 库的使用,验证码生成. 1.1 涉及到的知识点 PHP GD库 OOP编程 1.2 开发工具 sublime,一个方便快速的文本编辑器.点击桌面左下角: 应用程序菜单/开发

  • ThinkPHP3.2.2实现持久登录(记住我)功能的方法

    本文实例讲述了ThinkPHP3.2.2实现持久登录功能的方法.分享给大家供大家参考,具体如下: 实现持久登录,即用户在登录时,勾选了"记住我"之后,无论是否关闭浏览器,只要不退出登录,在指定的时间内始终保持登录状态(缺点是在另一台电脑上登录过后,之前那台电脑就不能继续保持登录状态). 首先,持久登陆使用 cookie 实现,但是 cookie 中不能保存用户密码这样重要的信息,即使加密过.解决方案是在用户登录表中新建3个字段identifier:第二身份标识,token:永久登录标识

  • PHP登录验证码的实现与使用方法

    本文实例讲述了PHP登录验证码的实现与使用方法.分享给大家供大家参考,具体如下: 1. 新建code.php验证码生成文件 在此之前必须打开php的GD库,修改php.ini文件的配置,取消extension=php_gd2.dll前面的分号.代码如下: <?php session_start(); //生成验证码图片 Header("Content-type: image/PNG"); $im = imagecreate(44,18); $back = ImageColorAl

随机推荐