我怎样才能确定ajax请求和curl请求来自同一个请求者?

时间:2014-09-15 13:34:05

标签: php ajax symfony session

我会尝试解释我的问题。 我使用php curl从跨域中的url获取响应,我在这个url中传递了一个密钥,我检查了我的symfony控制器,如果它存在于我的数据库中。然后我在json中返回一个回复。这个响应允许执行一个ajax脚本,这个脚本试图在jsonp中获取一个返回视图的其他url。

2个虚拟主机:mysite.dev& partnersite.api

//in partnersite.api
//httpPost & httpGet are curl functions
//$privateKey => get the key in a DB
$response = httpPost("http://mysite.dev/app_dev.php/api/permission/key", array('private_key' => $privateKey));
// or
$response = httpGet("http://mysite.dev/app_dev.php/api/permission/".$privateKey);
$jsonResp = array();
$jsonResp = json_decode($response, true);
if ($jsonRespP['access'] == 'granted'){
    echo '<script src="'.$jsonRespP['resp'].'" type="text/javascript"></script>';
    //there are some things here ...
    echo '<script>SlAPI({slug : "thing-to-display"});</script>';
}

//in mysite.dev (first controller) 
public function getApiPermissionAction() {
    $response = new JsonResponse();
    //check if key exists in DB and if exists :
    return  $response->setContent(json_encode(array(
        'access' => "granted",
        'resp' => "http://mysite.dev/app_dev.php/api/get_api", 
        //this is ajax script contained in js.html.twig and returning the views of the api
    )));
}

//in js.html.twig
function SlAPI(settings) {
    glob = settings;
    var SlAPI = {
        init: function() {
            if (glob.slug){
                {%  set url = urlSite ~ "/app_dev.php/api/thing/" %}
                url = "{{ url }}"+glob.slug; //==http://mysite.dev/app_dev.php/api/thing/thing-to-display
            }
            ajaxLoadUrl(url);
        }
    }
    SlAPI.init();
}

function ajaxLoadUrl(url, dataValue) {
    var dataValue = (dataValue == undefined ? "" : dataValue); //not used in this case but in others
    url += "?callback=?" ;
    JQuery.ajax({
        url: url,
        dataType: "jsonp",
        data: dataValue,
        xhrFields: {withCredentials: true},
        jsonpCallback: "successCallback",
    });
}

//in mysite.dev, 2nd controller
// Creating callback response
//$view is a way to a twig
public function callbackResponse($view, $params){
    $request = $this->getRequest();
    $response = new Response('', 200, array('content-type' => 'text/javascript'));
    $response->headers->set('Access-Control-Allow-Origin', '*');
    $response->send();

    if ($request->get('callback')) {
        $arrayNew = array("success" => $this->render($view, $params)->getContent());
        $jsonStr = json_encode($arrayNew);
        echo "{$request->get('callback')}( $jsonStr );";
        exit;
    }
}

//this works
//in partnersite.api I can see my view

我需要确保这两个电话来自同一个人/电脑。

问题是例如,我在一台可以拥有第一次通话密钥的计算机上,我获得了显示脚本的权限,如果我有不好的意图我可以复制源,然后给另一个人可以显示视图并做一些我不想要的事情。

我尝试使用会话,但如果我在第一个控制器中创建一个会话,我就无法在第二个控制器中获得相同的会话。 ID是不同的(我试图改变它,没有工作)。在使用ajax的第二次调用时,传递了一个phpsessid,因此第二个控制器中$ request中的会话就是那个。

其他信息是phpsessid doen改变,当我刷新并使用不同的虚拟主机(可能来自cookie)时,它是相同的,而创建的会话改变但这是正常的,但是你可以帮助我。

//following things are examples
//I added an other virtualhost partnersite2.api

//in partnersite.api
//I can start a session 
session_start();
echo session_id(); // hs8teh8qqqksdmj9030buvfpj7
echo '<br />'.$_COOKIE['PHPSESSID']; // hs8teh8qqqksdmj9030buvfpj7
// same

//in curl fonction
//I added CURLOPT_COOKIE => 'PHPSESSID=' . $_COOKIE['PHPSESSID']

//in mysite.dev (1st controller)
$session = $request->getSession();
$param = $session->getId(); // hs8teh8qqqksdmj9030buvfpj7

//in mysite.dev ajax get (2nd controller)
$session = $request->getSession();
$param = $session->getId(); // 8hmdf2r1imvoc55ioshojdd7i0
$param2 = $request->__toString(); // PHPSESSID: 8hmdf2r1imvoc55ioshojdd7i0

//in partnersite2.api 
session_start();
echo session_id(); // 9crfkb8tnmab04r75gv980dhb7
echo '<br />'.$_COOKIE['PHPSESSID']; // 9crfkb8tnmab04r75gv980dhb7
//it's different of when I call from partnersite.api 

//in mysite.dev (1st controller)
$session = $request->getSession();
$param = $session->getId(); // 9crfkb8tnmab04r75gv980dhb7

//in mysite.dev ajax get (2nd controller)
$session = $request->getSession();
$param = $session->getId(); // 8hmdf2r1imvoc55ioshojdd7i0
$param2 = $request->__toString(); // PHPSESSID: 8hmdf2r1imvoc55ioshojdd7i0
//it's same of when I call from partnersite.api 

//Im not sure session is a good way I don't know but may be something processing like a session in server side
// that I can identifie in the both controllers and makes me sure the both requests are from the same computer

所以我的问题是,是否存在像会话一样的东西,我可以在第一个控制器中初始化,例如带有id和一些参数,然后我可以通过id来检查它是否是&#39;是同一个客户谁做了这两个请求?

我知道我可以通过DB,但我不喜欢这种方式,但如果我必须,我会这样做。 例如,db中的库存时间戳然后像公钥一样发送它并将其传递给ajax请求然后检入db,如果它存在于db中并删除它。我不喜欢在db中存货,因为它&#39;暂时的。你觉得怎么样?可能是我做的一切都是错误的方式,告诉我pl。 TX

我希望你能理解我的问题并原谅我的语法我不是英语^^ tx

1 个答案:

答案 0 :(得分:0)

除了一些罕见的例外情况,会话在客户端使用cookie保留。这些Cookie使用扩展的HTTP标头Set-CookieCookie进行管理。这些是必要的,因为根据设计,HTTP是无状态的。

很难说没有看到任何代码,但是服务器返回的页面发起的任何AJAX请求也应该发送该AJAX请求的Cookie标头中的任何cookie,这反过来意味着即使是AJAX请求也应该使用服务器维护基于cookie的状态。

所以,我并不完全确定我理解你的问题,但是你说的是你如何尝试使用会话而不是或者它不能正常工作 - 我认为这是调试的地方需要开始。如果您的基本会话状态不能正常工作,那么除了这个AJAX之外,您可能还有其他问题。