QQ登录PHP Oauth示例

QQ登录PHP Oauth示例

演示地址:http://jiesc.net/oauth/login

  • 申请是立即通过的
  • 目前腾讯仅开放获取昵称和头像的API,以后会陆续推出其他API
  • 头像是QQ空间的,官方文档都是写QQ空间登录
  • 根据官方文档编写
PHP代码
  1. <?php   
  2. /**  
  3.  * 申请http://connect.opensns.qq.com/apply  
  4.  * 列表http://connect.opensns.qq.com/my  
  5.  */  
  6. session_start();   
  7. $qq_oauth_config = array(   
  8.     'oauth_consumer_key'=>'*******',//APP ID   
  9.     'oauth_consumer_secret'=>'******************',//APP KEY   
  10.     'oauth_callback'=>"http://www.955.cc/qq.php?action=reg",//这里修改为当前脚本,但是要保留?action=reg   
  11.     'oauth_request_token_url'=>"http://openapi.qzone.qq.com/oauth/qzoneoauth_request_token",   
  12.     'oauth_authorize_url'=>'http://openapi.qzone.qq.com/oauth/qzoneoauth_authorize',   
  13.     'oauth_request_access_token_url'=>'http://openapi.qzone.qq.com/oauth/qzoneoauth_access_token',   
  14.     'user_info_url' => 'http://openapi.qzone.qq.com/user/get_user_info',   
  15. );   
  16. $action = isset($_GET['action']) ? $_GET['action'] : '';   
  17.   
  18.   
  19. $qq = new qq_oauth($qq_oauth_config);   
  20. switch($action){   
  21.     //用户登录 Step1:请求临时token   
  22.     case 'login':   
  23.         $token = $qq->oauth_request_token();   
  24.         $_SESSION['oauth_token_secret'] = $token['oauth_token_secret'];   
  25.         $qq->authorize($token['oauth_token']);   
  26.     break;   
  27.     //Step4:Qzone引导用户跳转到第三方应用   
  28.     case 'reg':   
  29.         $qq->register_user();   
  30.         $access_token = $qq->request_access_token();   
  31.         if($token = $qq->save_access_token($access_token)){   
  32.             //保存,一般发给用户cookie,以及用户入库   
  33.             //var_dump($token);   
  34.             $_SESSION['oauth_token'] = $token['oauth_token'];   
  35.             $_SESSION['oauth_token_secret'] = $token['oauth_token_secret'];   
  36.             $_SESSION['openid'] = $token['openid'];   
  37.             header('Content-Type: text/html; charset=utf-8');   
  38.             $user_info = json_decode($qq->get_user_info());   
  39.             if($user_info->ret!=0){   
  40.                 exit("获取头像昵称时发生错误".$user_info->msg);   
  41.             } else {   
  42.                 echo 'QQ昵称:',$user_info->nickname,   
  43.                 '<img src="',$user_info->figureurl,'" />',   
  44.                 '<img src="',$user_info->figureurl_1,'" />',   
  45.                 '<img src="',$user_info->figureurl_2,'" />';   
  46.             }   
  47.                
  48.         }   
  49.     break;   
  50.     default :   
  51. }   
  52.   
  53.   
  54. class qq_oauth{   
  55.     private $config;   
  56.     function __construct($config){   
  57.         $this->config = $config;   
  58.     }   
  59.     /**  
  60.      * 返回配置  
  61.      * @param string $name  
  62.      *   
  63.      */  
  64.     function C($name){   
  65.         return isset($this->config[$name]) ?  $this->config[$name] : FALSE;   
  66.     }   
  67.     /**  
  68.      * 构建请求URL  
  69.      * @param string $url  
  70.      * @param array $params  
  71.      * @param string $oauth_token_secret  
  72.      *   
  73.      */  
  74.     function build_request_uri($url,$params=array(),$oauth_token_secret=''){   
  75.         $oauth_consumer_key = $this->C('oauth_consumer_key');   
  76.         $oauth_consumer_secret = $this->C('oauth_consumer_secret');   
  77.            
  78.         $params = array_merge(array(   
  79.             'oauth_version'=>'1.0',   
  80.             'oauth_signature_method'=>'HMAC-SHA1',   
  81.             'oauth_timestamp'=>time(),   
  82.             'oauth_nonce'=>rand(1000,99999999),   
  83.             'oauth_consumer_key'=>$oauth_consumer_key,   
  84.         ),$params);   
  85.         $encode_params = $params;   
  86.         ksort($encode_params);   
  87.         $oauth_signature = 'GET&'.urlencode($url).'&'.urlencode(http_build_query($encode_params));   
  88.         $oauth_signature = base64_encode(hash_hmac('sha1',$oauth_signature,$oauth_consumer_secret.'&'.$oauth_token_secret,true));   
  89.         $params['oauth_signature'] = $oauth_signature;   
  90.         return $url.'?'.http_build_query($params);   
  91.     }   
  92.     /**  
  93.      * 校验回调是否返回约定的参数   
  94.      */  
  95.     function check_callback(){   
  96.         if(isset($_GET['oauth_token']))   
  97.             if(isset($_GET['openid']))   
  98.                 if(isset($_GET['oauth_signature']))   
  99.                     if(isset($_GET['timestamp']))   
  100.                         if(isset($_GET['oauth_vericode']))   
  101.                             return true;   
  102.         return false;   
  103.     }   
  104.        
  105.     function get_contents($url){   
  106.         $curl = curl_init();   
  107.         curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);   
  108.         curl_setopt($curl,CURLOPT_URL,$url);   
  109.         return curl_exec($curl);   
  110.     }   
  111.     /**  
  112.      * Step1:请求临时token、Step2:生成未授权的临时token  
  113.      */  
  114.     function oauth_request_token(){   
  115.         $url = $this->build_request_uri($this->C('oauth_request_token_url'));   
  116.         $tmp_oauth_token = $this->get_contents($url);   
  117.         parse_str($tmp_oauth_token);   
  118.         /*  
  119.         oauth_token 未授权的临时token  
  120.         oauth_token_secret  token的密钥,该密钥仅限于临时token  
  121.         error_code  错误码  
  122.         */  
  123.         if(isset($error_code)) exit($error_code);   
  124.         return array(   
  125.             'oauth_token'=>$oauth_token,   
  126.             'oauth_token_secret'=>$oauth_token_secret  
  127.         );   
  128.     }   
  129.     /**  
  130.      * Step3:引导用户到Qzone的登录页  
  131.      * @param string $oauth_token 未授权的临时token  
  132.      */  
  133.     function authorize($oauth_token){   
  134.         $str = "HTTP/1.1 302 Found";   
  135.         header($str);   
  136.         $url = $this->C('oauth_authorize_url');   
  137.         $query_strings = http_build_query(array(   
  138.             'oauth_consumer_key'=>$this->C('oauth_consumer_key'),   
  139.             'oauth_token'=>$oauth_token,   
  140.             'oauth_callback'=>$this->C('oauth_callback'),   
  141.         ));   
  142.         header('Location: '.$url.'?'.$query_strings);   
  143.     }   
  144.     /**  
  145.      * Step4:Qzone引导用户跳转到第三方应用  
  146.      * @return bool 验证是否有效   
  147.      */  
  148.     function register_user(){   
  149.         /*  
  150.          * oauth_token  已授权的临时token  
  151.          * openid   腾讯用户对外的统一ID,该OpenID与用户QQ号码一一对应  
  152.          * oauth_signature  签名值,方便第三方来验证openid以及来源的可靠性。  
  153.          *      使用HMAC-SHA1算法:  
  154.          *      源串:openid+timestamp(串中间不要添加'+'符号)  
  155.          *      密钥:oauth_consumer_secret  
  156.          * timestamp    openid的时间戳  
  157.          * oauth_vericode   授权验证码。  
  158.          */  
  159.         if($this->check_callback()){   
  160.             //校验签名   
  161.             $signature = base64_encode(hash_hmac('sha1',$_GET['openid'].$_GET['timestamp'],$this->C('oauth_consumer_secret'),true));   
  162.             if(!emptyempty($_GET['oauth_signature']) && $signature==$_GET['oauth_signature']){   
  163.                 $_SESSION['oauth_token'] = $_GET['oauth_token'];   
  164.                 $_SESSION['oauth_vericode'] = $_GET['oauth_vericode'];   
  165.                 return;   
  166.             }   
  167.         }   
  168.         //校验未通过   
  169.         exit('UNKNOW REQUEST');   
  170.     }   
  171.     /**  
  172.      * Step5:请求access token   
  173.      */  
  174.     function request_access_token(){   
  175.         $url = $this->build_request_uri($this->C('oauth_request_access_token_url'),array(   
  176.             'oauth_token'=>$_SESSION['oauth_token'],   
  177.             'oauth_vericode'=>$_SESSION['oauth_vericode']   
  178.         ),$_SESSION['oauth_token_secret']);   
  179.         return $this->get_contents($url);   
  180.     }   
  181.     /**  
  182.      * Step6:生成access token (保存access token)  
  183.      *   
  184.      * 关于access_token  
  185.      * 目前access_token(及其secret)是长期有效的,和某一个openid对应,目前可以支持线下获取该openid的信息。   
  186.      * 当然,用户有权限在Qzone这边删除对第三方的授权,此时该access_token会失效,需要重新走整个流程让用户授权。  
  187.      * 以后会逐步丰富access_token的有效性,长期有效、短期有效、用户登录时才有效等。  
  188.      */  
  189.     function save_access_token($access_token_str){   
  190.         parse_str($access_token_str,$access_token_arr);   
  191.         if(isset($access_token_arr['error_code'])){   
  192.             return FALSE;   
  193.         } else {   
  194.             return $access_token_arr;   
  195.         }   
  196.     }   
  197.     /**  
  198.      * 目前腾讯仅开放该API  
  199.      * 获取登录用户信息,目前可获取用户昵称及头像信息。  
  200.      * http://openapi.qzone.qq.com/user/get_user_info  
  201.      */  
  202.     function get_user_info(){   
  203.         $url = $this->build_request_uri($this->C('user_info_url'),array(   
  204.             'oauth_token'=>$_SESSION['oauth_token'],   
  205.             'openid'=>$_SESSION['openid'],   
  206.         ),$_SESSION['oauth_token_secret']);   
  207.         return $this->get_contents($url);   
  208.     }   
  209. }   

本文转载自http://dev.meettea.com/show-95-1.html

 
posted @ 2011-04-21 10:18  andygoo  阅读(1575)  评论(0编辑  收藏  举报