QQ登录类
2015-3-31 22:02:09
(同一套代码, pc端不能登录, 但是, 手机和平板都可以正常登录.....)
1. 首先是库文件, 登录->授权->token->openid->获取用户信息
1 class QQ 2 { 3 public $appid = ''; 4 public $appkey = ''; 5 public $scope = 'get_user_info'; //权限用逗号隔开 6 public $callback = ''; 7 8 public $get_auth_code_url = 'https://graph.qq.com/oauth2.0/authorize'; 9 public $get_access_token_url = 'https://graph.qq.com/oauth2.0/token'; 10 public $get_openid_url = 'https://graph.qq.com/oauth2.0/me'; 11 public $get_user_info_url = 'https://graph.qq.com/user/get_user_info'; 12 13 public $access_token = ''; 14 public $openid = ''; 15 16 public function __construct($callback_url) 17 { 18 $this->callback = $callback_url; 19 } 20 21 public function login() 22 { 23 $objRedis = Fun::getInstance()->getRedis(); 24 $ip = Fun::getInstance()->getIP(); 25 26 //-------生成唯一随机串防CSRF攻击 27 $state = md5(uniqid(rand(), TRUE)); 28 $objRedis->iset('qqsdk'.$ip, 'state', $state); 29 30 //-------构造请求参数列表 31 $arrQueryArg = array( 32 'response_type' => 'code', 33 'client_id' => $this->appid, 34 'redirect_uri' => $this->callback, 35 'state' => $state, 36 'scope' => $this->scope 37 ); 38 39 $uri = http_build_query($arrQueryArg); 40 $login_url = $this->get_auth_code_url.'?'.$uri; 41 42 header("Location:$login_url"); 43 } 44 45 public function callback() 46 { 47 $objRedis = Fun::getInstance()->getRedis(); 48 $ip = Fun::getInstance()->getIP(); 49 $state = $objRedis->iget('qqsdk'.$ip, 'state'); 50 51 //--------验证state防止CSRF攻击 52 if($_GET['state'] != $state){ 53 exit('30001'); 54 } 55 56 //-------请求参数列表 57 $arrTokenArg = array( 58 'grant_type' => 'authorization_code', 59 'client_id' => $this->appid, 60 'redirect_uri' => $this->callback, 61 'client_secret' => $this->appkey, 62 'code' => $_GET['code'] 63 ); 64 //------构造请求access_token的url 65 $uri = http_build_query($arrTokenArg); 66 $token_url = $this->get_access_token_url.'?'.$uri; 67 $response = Fun::getInstance()->curl_get($token_url); 68 if(strpos($response, 'callback') !== false){ 69 70 $lpos = strpos($response, '('); 71 $rpos = strrpos($response, ')'); 72 $response = substr($response, $lpos + 1, $rpos - $lpos -1); 73 $msg = json_decode($response); 74 75 if(isset($msg->error)){ 76 var_dump($msg->error, $msg->error_description); 77 } 78 } 79 80 $params = array(); 81 parse_str($response, $params); 82 83 //---------获取openid 84 $arrTokenArg = array( 85 'access_token' =>$params['access_token'] 86 ); 87 $uri = http_build_query($arrTokenArg); 88 $openid_url = $this->get_openid_url.'?'.$uri; 89 $response = Fun::getInstance()->curl_get($openid_url); 90 91 //--------检测错误是否发生 92 if(strpos($response, 'callback') !== false){ 93 94 $lpos = strpos($response, '('); 95 $rpos = strrpos($response, ')'); 96 $response = substr($response, $lpos + 1, $rpos - $lpos -1); 97 } 98 99 $user = json_decode($response); 100 if(isset($user->error)){ 101 var_dump($user->error, $user->error_description);exit; 102 } 103 104 return array( 105 'access_token' => $params['access_token'], 106 'openid' => $user->openid 107 ); 108 109 } 110 111 public function get_user_info() 112 { 113 $qq_safe_info = $this->callback(); 114 $access_token = $qq_safe_info['access_token']; 115 $openid = $qq_safe_info['openid']; 116 $user_info_url = "{$this->get_user_info_url}?access_token={$access_token}&oauth_consumer_key={$this->appid}&openid={$openid}&format=json"; 117 $info = Fun::getInstance()->curl_get($user_info_url); 118 return array( 119 'openid' => $openid, 120 'user_info' => $info 121 ); 122 // $json_user_info = Fun::getInstance()->curl_get($user_info_url); 123 // return json_decode($json_user_info); 124 } 125 }
2. 其次是控制器调用代码, 调用QQ登录库文件, 以及获取并记录QQ登录信息
1 public function login() 2 { 3 $this->getLib('QQ', $this->qq_callback_url)->login(); 4 } 5 6 public function callback() 7 { 8 $user_info = $this->getLib('QQ', $this->qq_callback_url)->get_user_info(); 9 // $user_ip = Fun::getInstance()->getIP(); 10 $objRedis = $this->getLib('iredis'); 11 $objRedis->iset('qqsdk'.$this->cookierand, 'qquser', $user_info['user_info']); 12 $objUserInfo = json_decode($user_info['user_info']); 13 $this->loadBusiness('Bbs')->qqregister($user_info['openid'], $objUserInfo->nickname, $objUserInfo->figureurl_qq_1); 14 echo "<script>window.opener.location.reload();window.close();</script>"; 15 }
其中第14行代码的作用是, 刷新父窗口&&关闭弹出的QQ登录窗口
3. 最后是HTML代码, 在网页上放一个QQ登录按钮
1 <a href="#" onclick='toQzoneLogin()'><img src="http://zbf-img.qiniudn.com/qq_login.png" alt="QQ登录^_^" title="QQ登录^_^"></a> 2 <script type="text/javascript"> 3 //qq登录 4 var childWindow; 5 function toQzoneLogin() 6 { 7 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"); 8 } 9 </script>