操作方法:发送应用请求,从请求中获取数据(重定向到特定链接),而无需用户接受应用程序?

时间:2012-05-02 20:42:39

标签: facebook-graph-api facebook-php-sdk

假设用户向他的朋友发送应用请求, 此请求的目标是/my_app/catalog.php?ID=25

(不是索引页面) 在app请求中存储特定链接的唯一方法是使用请求的“data”字段。

当用户关注应用请求时,它会以index.php结尾(不是catalog.php?ID = 25)

如何在不知道用户ID的情况下从请求中提取数据字段? (没有他接受应用程序?)

我可以获得request_ids和app_token(不是user_access_tocken) 通过使用 https://graph.facebook.com/oauth/access_token?client_id= “$ GLOBALS [ 'APP_ID']。 ”&安培;“。$ GLOBALS [ 'app_secret']” client_secret =安培; grant_type = client_credentials

但没有用户ID并且他接受应用程序就无法获得“数据”字段 因此,不是用户能够在我的应用程序中看到他的朋友推荐他的产品,他看到了auth表单并接受应用程序对话框,而不知道这个应用程序是什么。

这不是一个正确的行为,我的未成年第一个用户必须在我的页面上看到一个链接,如果他想要执行操作或我的应用程序需要用户信息的权限 - 只有当“接受对话框”应该是使用

更新: 我猜Juicy是正确的,哪里没有其他方式获取应用程序请求网址,但要么将其存储在您自己的数据库中,要么要求用户接受该应用程序

如果其他人正在寻找此解决方法 这里有一些有用的东西:

//to deal with app requests: (this is part of overall page output preparation)
$rqlink="";
if((strlen($_REQUEST['request_ids'])>0)&&(strlen($user->id)>0))//user is logged no need for database
  {                                   
   if(($rq=getfbres("https://graph.facebook.com/?ids=".$_REQUEST['request_ids']."&access_token=".$_SESSION['access_token'] ))!==false)
     {
      $rqj = json_decode($rq);
      $request_ids = explode(',', $_REQUEST['request_ids']);
      foreach ($request_ids as $request_id)
       {
          $full_request_id=$request_id.'_'.$user->id;
          if(isset($rqj->$request_id->data)) $rqlink=$rqj->$request_id->data;
          //if(getfbres("https://graph.facebook.com/$full_request_id?method=delete&access_token=".$_SESSION['access_token'])===false)
          //{ echo "delete request error:". $GLOBALS['err']; exit;}
          break;
        } 
      }  
   }
elseif(strlen($_REQUEST['request_ids'])>0) //user is not logged, try to extract url from database
   {   
      $request_ids = explode(',', urldecode($_REQUEST['request_ids']));
      foreach ($request_ids as $request_id)
       {
         if(!isset($conn)){include_once "conn.php";  $conn=init_conn();}
         if(!($rez=mysql_query("select * from ff_app_rq where rq='".str_replace("'","''",$request_id)."'",$conn))) die ("Database error");
         if(mysql_num_rows($rez)>0)
         {
            $row=mysql_fetch_assoc($rez);
            $rqlink=$row['url'];
            mysql_free_result($rez);
            break;
         }
         else //request not found for some reason and user is not authorized
         {    //force pop-up authorization in order not to loose req_ids
            mysql_free_result($rez);
            echo("<script LANGUAGE='javascript'>window.open('/fblogin.php','_blank','width=900,height=450');</script>");
            break;
         }
        }
   }
 if(strlen($rqlink)>0)
     {
        session_write_close();
        echo("<script LANGUAGE='javascript'>document.location.href='".$rqlink."';</script>");
//        echo("<script LANGUAGE='javascript'>top.location.href='http".(getenv("HTTPS") == 'on'?"s":"")."://apps.facebook.com/".$GLOBALS['app_namespace']."/".$rqlink."';</script>");
        exit;
     }

这就是你推广的方式:

 function fire_promo()
 {
   FB.init({appId:'<?php echo $GLOBALS['app_id'];?>',status:true,cookie:true,frictionlessRequests:true,oauth:true});
   //(this will display popup with list of fb friends)
   getpage('ajforms.php?ID=<?php echo $id;?>&stage=promote_app','subcontent,-100,10,560,500,2,zzz');
   return false;
 }
 function sendRequestToManyRecipients()
 {
   var f=document.send_inv; //(this form lists all checked users)
   var ids="";
   for(var z=0;z<f.length;z++) if(f[z].name=='p') if(f[z].checked) {if(ids.length>0) ids+=',';ids+=f[z].value;}
   FB.ui({method:'apprequests',data:'catalog.php?ID=<?php echo $id;?>',message:'You have been invited to bla-bla',to:"'"+ids+"'"}, requestCallback);
 }

这是app请求javascript回调:

 function requestCallback(response)
 {
   if(response === undefined) return;
   //if(response.request===undefined) return;
   var req = getconn(); if(req) {req.open("HEAD",'fb_req.php?rq='+response.request+'&url='+encodeURIComponent('catalog.php?ID=<?php echo $id;?>',true));req.send(null);}
   //console.log(response.request);
   if(response.to.length === undefined) {} else if(response.to.length>0) alert('You have successfully promoted to '+response.to.length+' friends.\nThank You!');
 }

(getconn是一个初始化ajax通信的标准ajax函数)

这里是fb_req.php来记录应用程序请求:

<?php
if((strlen($_REQUEST['rq'])>0)&&(strlen($_REQUEST['url'])>0))
{
  include_once "conn.php";
  $conn=init_conn();
  $rez=mysql_query("insert into my_app_rq_table (rq,url,rq_date) VALUES('".str_replace("'","''",$_REQUEST['rq'])."','".str_replace("'","''",urldecode($_REQUEST['url']))."',now())",$conn);
  //if(!$rez) die ("Database error".mysql_error());
}
exit;
?>

和finnaly这里是fblogin.php用于弹出授权和刷新开启窗口时:

<?php
session_start();
include_once "params.php";
$code = $_REQUEST["code"];
if(strlen($code)>2)
{
  $my_url = "http".(getenv("HTTPS")=='on'?"s":"")."://".getdom().((($_SERVER['SERVER_PORT']=="80")||($_SERVER['SERVER_PORT']=="443"))?(""):(":".$_SERVER['SERVER_PORT']))."/fblogin.php?fb_redirect_url=".urlencode($_REQUEST['fb_redirect_url']);
  $token_url = "https://graph.facebook.com/oauth/access_token?client_id=".$GLOBALS['app_id']."&redirect_uri=".urlencode($my_url)."&client_secret=".$GLOBALS['app_secret']."&code=".$code;
  $access_token = getfbres($token_url);
  $graph_url = "https://graph.facebook.com/me?".$access_token;
  $rr=strpos($access_token,"&");
  if($rr>0) $access_token=substr($access_token,0,$rr);
  $access_token=str_replace("access_token=","",$access_token);
  $user = json_decode(getfbres($graph_url));
  if(strlen($user->id)>0)
   {
    $_SESSION['access_token']=$access_token;
    if(strlen($_REQUEST['fb_redirect_url'])>0)
      echo "<SCRIPT LANGUAGE='javascript'>\nwindow.opener.location.href='".urldecode($_REQUEST['fb_redirect_url'])."';\nwindow.close();</script>";
    else
      echo "<SCRIPT LANGUAGE='javascript'>\nwindow.opener.location.reload(true);\nwindow.close();</script>";
    exit;
   }
}

if(strlen($_SESSION['access_token'])>2)
{
  $graph_url = "https://graph.facebook.com/me?access_token=".$_SESSION['access_token'];
  $user = json_decode(getfbres($graph_url));
  if(strlen($user->id)>0)
   {
    if(strlen($_REQUEST['fb_redirect_url'])>0)
      echo "<SCRIPT LANGUAGE='javascript'>\nwindow.opener.location.href='".urldecode($_REQUEST['fb_redirect_url'])."';\nwindow.close();</script>";
    else
      echo "<SCRIPT LANGUAGE='javascript'>\nwindow.opener.location.reload(true);\nwindow.close();</script>";
    exit;
   }
}
$my_url = "http".(getenv("HTTPS")=='on'?"s":"")."://".getdom().((($_SERVER['SERVER_PORT']=="80")||($_SERVER['SERVER_PORT']=="443"))?(""):(":".$_SERVER['SERVER_PORT']))."/fblogin.php?fb_redirect_url=".urlencode($_REQUEST['fb_redirect_url']);
$dialog_url = "http://www.facebook.com/dialog/oauth?client_id=".$GLOBALS['app_id']."&redirect_uri=".urlencode($my_url).$GLOBALS['app_scope'];
//echo "<h1>".$_SESSION['log_attempts']."</h1>";
$_SESSION['log_attempts']=intval("0".$_SESSION['log_attempts'])+1;
if(intval("0".$_SESSION['log_attempts'])<5)
  echo("<script>document.location.href='".$dialog_url."';</script>");
else echo "<center><br><br><br><h1>Facebook Login failed</h1><br>Please refresh web page and try again.</center>";
exit;

function getdom()
{
 return strtolower(str_replace("www.","",$_SERVER['SERVER_NAME']));
}

function getfbres($url)
{
 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL, $url);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 curl_setopt($ch, CURLOPT_HEADER, 0);
 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
 $output = curl_exec($ch);
 $info = curl_getinfo($ch);
 if(curl_error($ch)) $err=curl_error($ch); else $err="";
 curl_close($ch);
 //echo "<pre>info:<br>"; var_dump($info); echo "<br>output:<br>"; echo $output;  if (strlen($err)>0) echo "<br>error:<br>$err"; echo "</pre><br>";
 if ($output === false || $info['http_code'] != 200)
  {
   // $GLOBALS['err']=$output."\nhttp code:".$info['http_code']."\n".$err;
 //   echo "<pre>info:<br>"; var_dump($info); echo "<br>output:<br>"; echo $output;  if (strlen($err)>0) echo "<br>error:<br>$err"; echo "</pre><br>";
 //   exit;
    return false;
  }
return $output;
}
?>

1 个答案:

答案 0 :(得分:0)

如果无法检索到data的事件(根据我使用旧格式access_token的应用APP_ID|APP_SECRET进行的测试不应该是这种情况),您可以轻松地将此详细信息保存在最后链接到您发送给用户时获得的请求id,然后根据您已有的数据发布重定向。