使用闪存发送数据时,将session_id设置为不可靠

时间:2010-07-31 12:20:12

标签: php flash uploadify sessionid

我在我的本地开发服务器和远程Web服务器上使用PHP版本5.3.2。

我正在尝试使用uploadify将多个文件上传到服务器。在接收脚本中,我想使用存储在会话中的数据,但是因为uploadify使用flash将文件发送到脚本,所以它不会发送会话cookie。
此问题的解决方法是将uploadify发送到GET或POST会话ID到脚本,但是我发现这非常不可靠。 在我的脚本中,我有以下内容:

<?php
ini_set('session.use_only_cookies', FALSE);
ini_set('session.use_trans_sid', TRUE);
session_name('SESSNAME');
session_start();
print_r($_SESSION);

脚本网址类似于script.php?SESSNAME = sessionid 我尝试使用如上所述的透明会话ID,并使用session_id手动设置id($ _ GET ['SESSNAME'])

当使用浏览器直接访问脚本并发送当前会话ID时,即使我手动删除会话cookie,总是也能正常工作。它也始终与我的本地服务器上的uploadify一起使用。但是,在远程服务器上使用uploadify时,它大约有20%的时间是完全随机的。没有模式。当我添加

时,它似乎工作频率更高
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 1);

到剧本,但这可能只是巧合。

有什么想法吗?

本地服务器信息:hxxp://www.dur.ac.uk/n.r.brook/info_local.php
远程服务器信息:hxxp://www.dur.ac.uk/n.r.brook/info.php
(对不起hxxp,没有权限发布多个链接!)


一些猜测......

做一些挖掘并查看脚本正在接收的标题,我想我可能已经确定了问题 您需要在使用uploadify时发送会话ID,因为在使用FileReference.upload()(我认为!)方法时,Flash不会发送cookie。但是,除了会话ID之外,在负载平衡环境(例如远程服务器)中还有BALANCEID cookie,它确定用户当前使用的服务器。 Flash不发送此cookie,因此负载均衡器有时会将请求发送到其他服务器,并且在此服务器上该会话不存在。

我通过在打印会话后设置会话变量来测试此行为。执行此操作并重复发送文件会出现问题 - 首先我得到一个空数组,但变量中的一些重复开始出现。

所以,如果以上都是真的,那么我的问题是如何让flash通过上传发送这些数据,以便负载均衡器知道要使用哪个服务器?或者这是一个失败的原因?


答案?

经过进一步研究,我发现了以下帖子 - hxxp://swfupload.org/forum/generaldiscussion/977
这表明无法使用FileReference.upload()发送cookie,因此如果要使用会话数据,uploadify不能与负载平衡服务器一起使用。但是,我想我现在将尝试一种解决方案,将链接到会话ID的数据保存到文件中。 uploadify接收脚本可以打开此文件并提取所需数据 这是我第一次使用任何基于Flash的体验,它没有改善我对该技术的看法!

2 个答案:

答案 0 :(得分:0)

我对此问题的解决方案是:

在“上传”页面中:

 file_put_contents($some_folder.'/'.session_id(), serialize($just_the_vars_you_will_be_using));

在加载uploadify的javascript中:

 var start = document.cookie.indexOf("PHPSESSID=");
 var end = document.cookie.indexOf(";", start); // First ; after start
 if (end == -1) end = document.cookie.length; // failed indexOf = -1
 var cookie = document.cookie.substring(start+10, end);
 $('#fileInput').uploadify({
            'uploader'  : 'uploadify.swf',
            'script'    : 'uploadify.php',
            'cancelImg' : 'cancel.png',
            'auto'      : true,
            'multi'     : true,
            'scriptData': { SESSID : cookie }
 });

在接收文件的脚本中:

 $vars = unserialize(file_get_contents($some_folder.'/'.$_POST['SESSID']));

如果您想在此脚本中回写“会话”,最后:

 file_put_contents($some_folder.'/'.$_POST['SESSID'], serialize($vars));

据我所知,不应该有任何与此相关的安全问题,因为您只会使用存储在文件中的少数变量(我只存储递增值和临时文件路径)。确保$ some_folder中有index.html以防止文件列表。

答案 1 :(得分:0)

从闪存发送时,您可以使用Cookie。 php需要使用Cookies来查找会话存储ID。存储在cookie中的值实际上是会话ID,cookie名称在大多数情况下是会话名称。 要在php中进行会话无法通过输入$ _SESSION ['name']来完成,但您可以创建自己包含的会话库。这将让php获得所有nassery值,你可以继续。

这是我在php中放在一起的会话库:

function SESSION_OPEN($PATH,$NAME){
    global $SESSION_PATH, $SESSION_NAME;
    $SESSION_PATH=$PATH;
    $SESSION_NAME=$NAME;

    return(true);
}

function SESSION_CLOSE(){
    return(true);
}

function SESSION_GET($ID){
    global $SESSION_PATH, $SESSION_NAME;
    $STR_PATH="$SESSION_PATH/USES_".session_id()."_$ID";

    if($RESOURCE = @fopen($STR_PATH,"r")){
        $CONTENT = @fread($RESOURCE ,filesize($STR_PATH));  
        return($CONTENT);   
    }else{
        return(false);  
    }
}

function SESSION_PUT($ID,$VALUE){
    global $SESSION_PATH, $SESSION_NAME;
    $STR_PATH="$SESSION_PATH/USES_".session_id()."_$ID";

    if($RESOURCE = @fopen($STR_PATH,"w")){
        fwrite($RESOURCE , $VALUE );    
        return(true);   
    }else{
        return(false);  
    }
}

function SESSION_DEST($ID){
    global $SESSION_PATH, $SESSION_NAME;
    $STR_PATH="$SESSION_PATH/USES_".session_id()."_$ID";

    return(@unlink($STR_PATH));
}

function SESSION_GC($MAX_EXECUTION){
    return(true);   
}

session_set_save_handler("SESSION_OPEN","SESSION_CLOSE","SESSION_GET","SESSION_PUT","SESSION_DEST","SESSION_GC");