2015-3-31 22:02:09

(同一套代码, pc端不能登录, 但是, 手机和平板都可以正常登录.....)

1. 首先是库文件, 登录->授权->token->openid->获取用户信息

 class QQ
{
public $appid = '';
public $appkey = '';
public $scope = 'get_user_info'; //权限用逗号隔开
public $callback = ''; public $get_auth_code_url = 'https://graph.qq.com/oauth2.0/authorize';
public $get_access_token_url = 'https://graph.qq.com/oauth2.0/token';
public $get_openid_url = 'https://graph.qq.com/oauth2.0/me';
public $get_user_info_url = 'https://graph.qq.com/user/get_user_info'; public $access_token = '';
public $openid = ''; public function __construct($callback_url)
{
$this->callback = $callback_url;
} public function login()
{
$objRedis = Fun::getInstance()->getRedis();
$ip = Fun::getInstance()->getIP(); //-------生成唯一随机串防CSRF攻击
$state = md5(uniqid(rand(), TRUE));
$objRedis->iset('qqsdk'.$ip, 'state', $state); //-------构造请求参数列表
$arrQueryArg = array(
'response_type' => 'code',
'client_id' => $this->appid,
'redirect_uri' => $this->callback,
'state' => $state,
'scope' => $this->scope
); $uri = http_build_query($arrQueryArg);
$login_url = $this->get_auth_code_url.'?'.$uri; header("Location:$login_url");
} public function callback()
{
$objRedis = Fun::getInstance()->getRedis();
$ip = Fun::getInstance()->getIP();
$state = $objRedis->iget('qqsdk'.$ip, 'state'); //--------验证state防止CSRF攻击
if($_GET['state'] != $state){
exit('30001');
} //-------请求参数列表
$arrTokenArg = array(
'grant_type' => 'authorization_code',
'client_id' => $this->appid,
'redirect_uri' => $this->callback,
'client_secret' => $this->appkey,
'code' => $_GET['code']
);
//------构造请求access_token的url
$uri = http_build_query($arrTokenArg);
$token_url = $this->get_access_token_url.'?'.$uri;
$response = Fun::getInstance()->curl_get($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)){
var_dump($msg->error, $msg->error_description);
}
} $params = array();
parse_str($response, $params); //---------获取openid
$arrTokenArg = array(
'access_token' =>$params['access_token']
);
$uri = http_build_query($arrTokenArg);
$openid_url = $this->get_openid_url.'?'.$uri;
$response = Fun::getInstance()->curl_get($openid_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)){
var_dump($user->error, $user->error_description);exit;
} return array(
'access_token' => $params['access_token'],
'openid' => $user->openid
); } public function get_user_info()
{
$qq_safe_info = $this->callback();
$access_token = $qq_safe_info['access_token'];
$openid = $qq_safe_info['openid'];
$user_info_url = "{$this->get_user_info_url}?access_token={$access_token}&oauth_consumer_key={$this->appid}&openid={$openid}&format=json";
$info = Fun::getInstance()->curl_get($user_info_url);
return array(
'openid' => $openid,
'user_info' => $info
);
// $json_user_info = Fun::getInstance()->curl_get($user_info_url);
// return json_decode($json_user_info);
}
}

2. 其次是控制器调用代码, 调用QQ登录库文件, 以及获取并记录QQ登录信息

 public function login()
{
$this->getLib('QQ', $this->qq_callback_url)->login();
} public function callback()
{
$user_info = $this->getLib('QQ', $this->qq_callback_url)->get_user_info();
// $user_ip = Fun::getInstance()->getIP();
$objRedis = $this->getLib('iredis');
$objRedis->iset('qqsdk'.$this->cookierand, 'qquser', $user_info['user_info']);
$objUserInfo = json_decode($user_info['user_info']);
$this->loadBusiness('Bbs')->qqregister($user_info['openid'], $objUserInfo->nickname, $objUserInfo->figureurl_qq_1);
echo "<script>window.opener.location.reload();window.close();</script>";
}

其中第14行代码的作用是, 刷新父窗口&&关闭弹出的QQ登录窗口

3. 最后是HTML代码, 在网页上放一个QQ登录按钮

 <a href="#" onclick='toQzoneLogin()'><img src="http://zbf-img.qiniudn.com/qq_login.png" alt="QQ登录^_^" title="QQ登录^_^"></a>
<script type="text/javascript">
//qq登录
var childWindow;
function toQzoneLogin()
{
childWindow = window.open("http://www.zhangzhibin.com/qq/index/login","TencentLogin","width=450,height=320,menubar=0,scrollbars=1, resizable=1,status=1,titlebar=0,toolbar=0,location=1");
}
</script>

QQ登录类的更多相关文章

  1. 使用Java的Frame类编写的QQ登录界面

    public static void main(String[] args) { Frame f = new Frame(); //关闭窗体 f.addWindowListener(new Windo ...

  2. android实现第三方登录之QQ登录

    首先,当然是在腾讯开放平台(http://open.qq.com/)注册成为开发者,然后获取APP ID 1.下载SDK http://wiki.open.qq.com/wiki/mobile/SDK ...

  3. Android(java)学习笔记209:采用get请求提交数据到服务器(qq登录案例)

    1.GET请求:    组拼url的路径,把提交的数据拼装url的后面,提交给服务器. 缺点:(1)安全性(Android下提交数据组拼隐藏在代码中,不存在安全问题)  (2)长度有限不能超过4K(h ...

  4. 界面编程模仿篇(QQ登录界面逼真篇)

    写了好多天的爬虫,偷空前前后后用了两天的时间(排除吃饭睡觉)写完了这个QQ登录界面,看起来还凑和着吧,如果是的大神的,莫见笑,纯属业余作品,废话先不多说,截图如下,其中第二幅图片中的红色方框部份有待完 ...

  5. Android(java)学习笔记213:开源框架post和get方式提交数据(qq登录案例)

    1.前面提到Http的get/post方式  . HttpClient方式,实际工作的时候不常用到,因为这些方式编写代码是很麻烦的 2.Android应用会经常使用http协议进行传输,网上会有很完善 ...

  6. 用SignalR做类似QQ登录的应用

    原文:用SignalR做类似QQ登录的应用 首先通过NuGet下载signalr包 在工程下新建一个类,继承Hub public class DemoHub:Hub { public class Us ...

  7. IdentityServer4(10)- 添加对外部认证的支持之QQ登录

    前言 前面我们提到过IdentityServer4是可以添加外部认证的,如果外部认证支持OAuth2,那么添加到IdentityServer4是非常简单的,在ASP.NET Core下提供了非常多的外 ...

  8. 使用SpringSocial开发QQ登录

    ⒈编写QQ用户对应的数据结构 package cn.coreqi.social.qq.entities; /** * 封装QQ的用户信息 */ public class QQUserInfo { /* ...

  9. 第三方登录:QQ登录实现(OAuth2.0)

    一.创建应用 1.在 QQ互联 创建应用 地址:https://connect.qq.com/manage.html#/ 然后进行实名认证,创建应用,审核通过 然后点击查看,可以获得 APP ID 和 ...

随机推荐

  1. Selenium 代码收集

    [转载]使用Selenium2测试含有iframe的Ajax网页  原文地址:http://www.cnblogs.com/hexin0614/archive/2012/03/24/2415670.h ...

  2. 简谈switch case

    工作中从buff里截取了一个字符串,然后和配置文件中的字符串名字对比 ,如果一样,处理,不一样,elseif 再判断,再处理! switch(){case : case :...... }先说语法,再 ...

  3. mapreduce 自定义数据类型的简单的应用

    本文以手机流量统计为例: 日志中包含下面字段 现在需要统计手机的上行数据包,下行数据包,上行总流量,下行总流量. 分析:可以以手机号为key 以上4个字段为value传传递数据. 这样则需要自己定义一 ...

  4. virtualBox切换到无缝模式后,如何调出菜单

    host+c host就是指右边的那个ctrl键

  5. HTTP报文详解

    二.HTTP请求首部字段 1 Accept 2 Accept-Charset 3 Accept-Encoding 4 Accept-Language 5 Authorization 6

  6. Error: [ng:areq] Argument 'xxxx' is not a function, got undefined

    "Error: [ng:areq] Argument 'keywords' is not a function, got undefined" 代码类似这样的: <div n ...

  7. web开发前端学习

    bootstrap:  http://www.bootcss.com/ bootstrap:   http://bootsnipp.com/snippets/featured/single-colum ...

  8. Centos ftp服务器安装配置

    yum install vsftpd [root@localhost ftp]# /sbin/service vsftpd restart 查看FTP目录 # more /etc/passwd|gre ...

  9. javascript高级程序设计---DOM

    DOM是文档对象模型的简称,DOM的基本思想是把结构化文档解析成一系列的节点,由这些节点组成数装的DOM树,所有的这些节点和最终的树状结构都有统一的对外接口,达到使用编程语言操作文档的目的,DOM可以 ...

  10. C 语言 typedef

    虽然#define语句看起来象typedef,但实际上却有本质上的差别.对于#define来说,仅在编译前对源代码进行了字符串替换处理:而对于typedef来说,它建立了一个新的数据类型别名.由此可见 ...