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在Web开发领域的优势
Oct 09 PHP
php 正则表达式小结
Aug 31 PHP
PHP统计目录下的文件总数及代码行数(去除注释及空行)
Jan 17 PHP
php中Y2K38的漏洞解决方法实例分析
Sep 22 PHP
完整删除ecshop中获取店铺信息的API
Dec 24 PHP
php导入excel文件到mysql数据库的方法
Jan 14 PHP
php截取html字符串及自动补全html标签的方法
Jan 15 PHP
PHP扩展Memcache分布式部署方案
Dec 06 PHP
PHP实现多级分类生成树的方法示例
Feb 07 PHP
PHP远程连接oracle数据库操作实现方法图文详解
Apr 11 PHP
PHP判断函数是否被定义的方法
Jun 21 PHP
php计数排序算法的实现代码(附四个实例代码)
Mar 31 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
11个PHP 分页脚本推荐
2011/08/15 PHP
解析WordPress中函数钩子hook的作用及基本用法
2015/12/22 PHP
用函数式编程技术编写优美的 JavaScript
2006/11/25 Javascript
js实现的点击div区域外隐藏div区域
2014/06/30 Javascript
js实现带圆角的多级下拉菜单效果
2015/08/28 Javascript
javascript函数中的3个高级技巧
2016/09/22 Javascript
javascript深拷贝和浅拷贝详解
2017/02/14 Javascript
PHP实现本地图片上传和验证功能
2017/02/27 Javascript
JavaScript定义函数的三种实现方法
2017/09/23 Javascript
详解使用Typescript开发node.js项目(简单的环境配置)
2017/10/09 Javascript
深度了解vue.js中hooks的相关知识
2019/06/14 Javascript
让你30分钟快速掌握vue3教程
2020/10/26 Javascript
Linux下使用python调用top命令获得CPU利用率
2015/03/10 Python
菜鸟使用python实现正则检测密码合法性
2016/01/05 Python
python实现多线程的方式及多条命令并发执行
2016/06/07 Python
详解appium+python 启动一个app步骤
2017/12/20 Python
Python解析命令行读取参数--argparse模块使用方法
2018/01/23 Python
django+xadmin+djcelery实现后台管理定时任务
2018/08/14 Python
python生成多个只含0,1元素的随机数组或列表的实例
2018/11/12 Python
利用Django提供的ModelForm增删改数据的方法
2019/01/06 Python
Python数据类型之Dict字典实例详解
2019/05/07 Python
Python 多线程其他属性以及继承Thread类详解
2019/08/28 Python
使用python matploblib库绘制准确率,损失率折线图
2020/06/16 Python
django 将自带的数据库sqlite3改成mysql实例
2020/07/09 Python
详解python UDP 编程
2020/08/24 Python
python opencv角点检测连线功能的实现代码
2020/11/24 Python
纯CSS3实现Material Design效果
2017/03/09 HTML / CSS
10分钟理解CSS3 FlexBox弹性布局
2018/12/20 HTML / CSS
New Balance美国官网:运动鞋和健身服装
2017/04/11 全球购物
大学生职业生涯规划书模板
2014/01/18 职场文书
关于有小孩的离婚协议书
2014/10/26 职场文书
2014年物资管理工作总结
2014/12/02 职场文书
大学学生个人总结
2015/02/15 职场文书
2016高校自主招生自荐信范文
2016/01/28 职场文书
应用最多的公文《通知》如何写?
2019/04/02 职场文书
3招让你摆脱即兴讲话冷场尴尬
2019/08/08 职场文书