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. java中如何将字符串数组转换成字符串(转)

    如果是 “字符串数组” 转 “字符串”,只能通过循环,没有其它方法 String[] str = {"abc", "bcd", "def"} ...

  2. 弹出框一 之 基于bootstrap和jquery的自定义弹出框

    (function ($) { window.Ewin = function () { var html = '<div id="[Id]" class="moda ...

  3. yaf自动加载文件

    models下面的文件 例如:Article.php 类名必须是:ArticleModel 调用时:$article_models = new ArticleModel(); library下面的文件 ...

  4. hdu4975 A simple Gaussian elimination problem.(正确解法 最大流+删边判环)(Updated 2014-10-16)

    这题标程是错的,网上很多题解也是错的. http://acm.hdu.edu.cn/showproblem.php?pid=4975 2014 Multi-University Training Co ...

  5. 让ie浏览器支持html5新标签的解决方法(使用html5shiv)

    没估计错的话旧版浏览器都是不识别这些新增的标签所以都是用行内元素来处理解决的,所以,有一个解决办法的突破口就是让它变成块状元素就不会处于同一行了,这样在新旧浏览器都是可以显示同样的效果,再者就是让浏览 ...

  6. 【学习】一本案例驱动的jQuery Mobile入门书

    清华大学出版社推出的<构建跨平台APP:jQuery Mobile移动应用实战> 提供的全是jQuery Mobile的案例: 手机入侵 题库应用 音乐专辑 通讯录 新闻列表 销售排名 九 ...

  7. STM32 之 NVIC(中断向量、优先级) 简述

    一.背景 需要使用STM32的CAN进行通信,经过一系列配置后,已可正常收发,还剩下一个CAN通信的错误处理.可错 误中断使能寄存器已经配置使能了,出错后就是无法进入"CAN1_SCE_IR ...

  8. linux下svn命令使用大全

    最近经常使用svn进行代码管理,这些命令老是记不住,得经常上网查,终于找了一个linux下svn命令使用大全:1.将文件checkout到本地目录 svn checkout path(path是服务器 ...

  9. SQL2008"阻止保存要求重新创建表的更改"问题的解决

    在sql server2008中修改数据库中某个字段的时候,会弹出以下提示: 导致数据库表在表设计界面无法修改,好像只能通过sql语句修改,其实只要改一下sql server的一个配置项就可以了,具体 ...

  10. servlet和http请求

    1.servlet servlet是和平台无关的服务器组件,可以交互式的来浏览和修改数据,生成动态的web内容.它运行于 servlet容器中2.servlet容器 servlet容器负责servle ...