HowTo: отправить запрос приложения и получить данные из запроса (для перенаправления на определенную ссылку) без принятия пользователем приложения?

скажем, пользователь отправляет запросы приложений своим друзьям, этот запрос будет нацелен на что-то /my_app/catalog.php?ID=25

(не страница индекса) единственный способ сохранить конкретную ссылку в запросе приложения - использовать поле «данные» запроса.

когда пользователь выполняет запрос приложения, он попадает в index.php (не в catalog.php?ID=25)

как я могу извлечь поле данных из запроса, не зная идентификатора пользователя? (и без того, чтобы он принял приложение?)

я могу получить request_ids, а также app_token (не user_access_tocken), используя https://graph.facebook.com/oauth/access_token?client_id=".$GLOBALS['app_id']."&client_secret=".$GLOBALS['app_secret']."&grant_type=client_credentials

но без идентификатора пользователя и его принятия приложения невозможно получить поле «данные», поэтому вместо того, чтобы пользователь мог видеть продукт в моем приложении, который ему рекомендовал его друг, он видит формы аутентификации и принимает диалоги приложения, не зная, что это приложение о.

это неправильное поведение, и, насколько я понимаю, первый пользователь должен был увидеть ссылку на моей странице, а затем, если он захочет выполнить действия или моему приложению нужны разрешения для информации пользователя - только тогда, когда следует использовать «диалог принятия».

ОБНОВЛЕНИЕ: я думаю, что Juicy прав, и где нет другого способа получить URL-адрес запроса приложения, кроме как сохранить его в своей собственной базе данных или потребовать, чтобы пользователь принял приложение

на случай, если кто-то еще ищет этот обходной путь, вот несколько полезных вещей:

//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);
 }

вот обратный вызов 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;
?>

и, наконец, вот 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;
}
?>

person Alex Novikov    schedule 02.05.2012    source источник
comment
stackoverflow.com/a/7685307/7506 должен ответить на ваш вопрос.   -  person Kemal    schedule 23.05.2012


Ответы (1)


Событие, если data не может быть получено (что не должно иметь место в соответствии с моими тестами с использованием приложения access_token в старом формате APP_ID|APP_SECRET), вы можете легко сохранить эти данные на своем конце, связанные с запросом id, который вы получаете при отправке пользователю, а затем перенаправить на основе данных, которые у вас уже есть.

person Juicy Scripter    schedule 23.05.2012