PHP版QQ互联OAuth示例代码分享


Posted in PHP onJuly 05, 2015

由于国内QQ用户的普遍性,所以现在各大网站都尽可能的提供QQ登陆口,下面我们来看看php版,给大家参考下

/**
 * QQ互联 oauth
 * @author dyllen
 *
 */
class Oauth
{
  //取Authorization Code Url
  const PC_CODE_URL = 'https://graph.qq.com/oauth2.0/authorize';
   
  //取Access Token Url
  const PC_ACCESS_TOKEN_URL = 'https://graph.qq.com/oauth2.0/token';
   
  //取用户 Open Id Url
  const OPEN_ID_URL = 'https://graph.qq.com/oauth2.0/me';
   
  //用户授权之后的回调地址
  public $redirectUri = null;
   
  // App Id
  public $appid = null;
   
  //App Key
  public $appKey = null;
   
  //授权列表
  //字符串,多个用逗号隔开
  public $scope = null;
   
  //授权code
  public $code = null;
   
  //续期access token的凭证
  public $refreshToken = null;
   
  //access token
  public $accessToken = null;
   
  //access token 有效期,单位秒
  public $expiresIn = null;
   
  //state
  public $state = null;
   
  public $openid = null;
   
  //construct
  public function __construct($config=[])
  {
    foreach($config as $key => $value) {
      $this->$key = $value;
    }
  }
   
  /**
   * 得到获取Code的url
   * @throws \InvalidArgumentException
   * @return string
   */
  public function codeUrl()
  {
    if (!$this->redirectUri) {
      throw new \Exception('parameter $redirectUri must be set.');
    }
    $query = [
        'response_type' => 'code',
        'client_id' => $this->appid,
        'redirect_uri' => $this->redirectUri,
        'state' => $this->getState(),
        'scope' => $this->scope,
    ];
   
    return self::PC_CODE_URL . '?' . http_build_query($query);
  }
   
  /**
   * 取access token
   * @throws Exception
   * @return boolean
   */
  public function getAccessToken()
  {
    $params = [
        'grant_type' => 'authorization_code',
        'client_id' => $this->appid,
        'client_secret' => $this->appKey,
        'code' => $this->code,
        'redirect_uri' => $this->redirectUri,
    ];
   
    $url = self::PC_ACCESS_TOKEN_URL . '?' . http_build_query($params);
    $content = $this->getUrl($url);
    parse_str($content, $res);
    if ( !isset($res['access_token']) ) {
      $this->thrwoError($content);
    }
   
    $this->accessToken = $res['access_token'];
    $this->expiresIn = $res['expires_in'];
    $this->refreshToken = $res['refresh_token'];
   
    return true;
  }
   
  /**
   * 刷新access token
   * @throws Exception
   * @return boolean
   */
  public function refreshToken()
  {
    $params = [
        'grant_type' => 'refresh_token',
        'client_id' => $this->appid,
        'client_secret' => $this->appKey,
        'refresh_token' => $this->refreshToken,
    ];
   
    $url = self::PC_ACCESS_TOKEN_URL . '?' . http_build_query($params);
    $content = $this->getUrl($url);
    parse_str($content, $res);
    if ( !isset($res['access_token']) ) {
      $this->thrwoError($content);
    }
   
    $this->accessToken = $res['access_token'];
    $this->expiresIn = $res['expires_in'];
    $this->refreshToken = $res['refresh_token'];
   
    return true;
  }
   
  /**
   * 取用户open id
   * @return string
   */
  public function getOpenid()
  {
    $params = [
        'access_token' => $this->accessToken,
    ];
   
    $url = self::OPEN_ID_URL . '?' . http_build_query($params);
       
    $this->openid = $this->parseOpenid( $this->getUrl($url) );
     
    return $this->openid;
  }
   
  /**
   * get方式取url内容
   * @param string $url
   * @return mixed
   */
  public function getUrl($url)
  {
    $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);
   
    return $response;
  }
   
  /**
   * post方式取url内容
   * @param string $url
   * @param array $keysArr
   * @param number $flag
   * @return mixed
   */
  public function postUrl($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;
  }
   
   
  /**
   * 取state
   * @return string
   */
  protected function getState()
  {
    $this->state = md5(uniqid(rand(), true));
    //state暂存在缓存里面
    //自己定义
        //。。。。。。。。。
   
    return $this->state;
  }
   
  /**
   * 验证state
   * @return boolean
   */
  protected function verifyState()
  {
    //。。。。。。。
  }
   
  /**
   * 抛出异常
   * @param string $error
   * @throws \Exception
   */
  protected function thrwoError($error)
  {
    $subError = substr($error, strpos($error, "{"));
    $subError = strstr($subError, "}", true) . "}";
    $error = json_decode($subError, true);
     
    throw new \Exception($error['error_description'], (int)$error['error']);
  }
   
  /**
   * 从获取openid接口的返回数据中解析出openid
   * @param string $str
   * @return string
   */
  protected function parseOpenid($str)
  {
    $subStr = substr($str, strpos($str, "{"));
    $subStr = strstr($subStr, "}", true) . "}";
    $strArr = json_decode($subStr, true);
    if(!isset($strArr['openid'])) {
      $this->thrwoError($str);
    }
     
    return $strArr['openid'];
  }
}

以上所述就是本文的全部内容了,希望大家能够喜欢。

PHP 相关文章推荐
PHP MSSQL 存储过程的方法
Dec 24 PHP
php文件怎么打开 如何执行php文件
Dec 21 PHP
php开发留言板的CRUD(增,删,改,查)操作
Apr 19 PHP
浅谈php serialize()与unserialize()的用法
Jun 05 PHP
PHP页面中文乱码分析
Oct 29 PHP
php实现图片添加水印功能
Feb 13 PHP
php导入大量数据到mysql性能优化技巧
Dec 29 PHP
简单介绍win7下搭建apache+php+mysql开发环境
Aug 06 PHP
php通过curl添加cookie伪造登陆抓取数据的方法
Apr 02 PHP
PHP的swoole扩展安装方法详细教程
May 18 PHP
php+mysql查询实现无限下级分类树输出示例
Oct 03 PHP
解决windows上php xdebug 无法调试的问题
Feb 19 PHP
PHP 获取ip地址代码汇总
Jul 05 #PHP
PHP中$_SERVER使用说明
Jul 05 #PHP
php实现短信发送代码
Jul 05 #PHP
phpMyAdmin安装并配置允许空密码登录
Jul 04 #PHP
Ubuntu下安装PHP的mongodb扩展操作命令
Jul 04 #PHP
Cygwin中安装PHP方法步骤
Jul 04 #PHP
php使用Session和文件统计在线人数
Jul 04 #PHP
You might like
树型结构列出指定目录里所有文件的PHP类
2006/10/09 PHP
利用递归把多维数组转为一维数组的函数
2006/10/09 PHP
phpExcel导出大量数据出现内存溢出错误的解决方法
2013/02/28 PHP
Javascript实例教程(19) 使用HoTMetal(2)
2006/12/23 Javascript
JavaScript 监听textarea中按键事件
2009/10/08 Javascript
js实现收缩菜单效果实例代码
2013/10/30 Javascript
使用bootstrap typeahead插件实现输入框自动补全之问题及解决办法
2016/07/07 Javascript
js实现精确到毫秒的倒计时效果
2016/08/05 Javascript
详解vue-router 2.0 常用基础知识点之router-link
2017/05/10 Javascript
Vue.js 的移动端组件库mint-ui实现无限滚动加载更多的方法
2017/12/23 Javascript
Vue中父子组件通讯之todolist组件功能开发
2018/05/21 Javascript
Webpack 4.x搭建react开发环境的方法步骤
2018/08/15 Javascript
Puppeteer环境搭建的详细步骤
2018/09/21 Javascript
详解vue beforeEach 死循环问题解决方法
2020/02/25 Javascript
微信小程序开发(二):页面跳转并传参操作示例
2020/06/01 Javascript
前端使用crypto.js进行加密的函数代码
2020/08/16 Javascript
vue实现tab栏点击高亮效果
2020/08/19 Javascript
Python和Perl绘制中国北京跑步地图的方法
2016/03/03 Python
Python中的os.path路径模块中的操作方法总结
2016/07/07 Python
Python+Socket实现基于TCP协议的客户与服务端中文自动回复聊天功能示例
2017/08/31 Python
python代码 输入数字使其反向输出的方法
2018/12/22 Python
python找出因数与质因数的方法
2019/07/25 Python
Python统计分析模块statistics用法示例
2019/09/06 Python
Python实现数值积分方式
2019/11/20 Python
TensorFlow索引与切片的实现方法
2019/11/20 Python
Python3搭建http服务器的实现代码
2020/02/11 Python
荷兰游戏商店:Allyouplay
2019/03/16 全球购物
JYSK加拿大:购买家具、床垫、家居装饰等
2020/02/14 全球购物
游戏商店:Eneba
2020/04/25 全球购物
培训讲师邀请函
2014/01/10 职场文书
会计专业求职信范文
2014/03/16 职场文书
新闻编辑求职信
2014/04/09 职场文书
国家税务局干部作风整顿整改措施
2014/09/18 职场文书
社区元宵节活动总结
2015/02/06 职场文书
Python 用户输入和while循环的操作
2021/05/23 Python
Python之Matplotlib绘制热力图和面积图
2022/04/13 Python