2010-09-13 39 views
0

我正在爲客戶的網站開發應用程序。 這是一個故事,這家公司使用名爲Synology的應用程序/ HDD,基本上它是一個連接到互聯網的硬盤盒,可以通過預先創建的帳戶訪問客戶端的文件。 這個接口是用CGI編寫的,我沒有訪問這個盒子(不同的網絡和位置)。幫助PHP,POST,COOKIE,JQUERY

我們想要做的是允許從主網站(我正在構建)的登錄表單繞過(至少對用戶:D)應用程序登錄表單。

我顯然不能對不同的域做一個jQuery ajax請求,它不會工作。所以我所做的就是

1)網站上的表格使用jQuery:

$("#login_submit").click(function(){ 
    var username= $("input#login_username").val(); 
    var passwd= $("input#login_passwd").val(); 
    var post_string = "username=" + username + "&passwd=" + passwd ; 
    $.ajax({ 
     type : "POST", 
     url: "login.php", 
     data : post_string, 
     success: function(response){ 

      if (response){ 
       $('.result').html("OK"); 
       window.location = "http://XX.XX.net:5000/webman/index.cgi"; 
      } 
      else { 
       $('.result').html("INVALID"); 
      } 
     } 
    }) 
    return false; 
} 

2)呼籲通過POST提交傳遞用戶和密碼的login.php頁面,PHP頁面使得向遠程Synology服務器發送HTTP POST請求,並在JSON中給我一個響應,顯然(?)我將其轉換爲PHP數組,以便我可以查看「成功」鍵是true還是false,如果爲true,jquery代碼將打印一個OK消息並重定向到遠程sylonogy服務器,我可以訪問我的數據記錄!

<?php 
function do_post_request($url, $data, $optional_headers = null) 
{ 
    $params = array('http' => array(
       'method' => 'POST', 
       'content' => $data 
      )); 
    if ($optional_headers !== null) { 
    $params['http']['header'] = $optional_headers; 
    } 
    $ctx = stream_context_create($params); 
    $fp = @fopen($url, 'rb', false, $ctx); 
    if (!$fp) { 
    throw new Exception("Problem with $url, $php_errormsg"); 
    } 
    $response = @stream_get_contents($fp); 
    if ($response === false) { 
    throw new Exception("Problem reading data from $url, $php_errormsg"); 
    } 
    return $response; 
} 

if ($_SERVER['REQUEST_METHOD'] == "POST"){ 
    $username = $_POST["username"]; 
    $passwd = $_POST["passwd"]; 

    $response =json_decode(do_post_request($url = "http://XX.XX.net:5000/webman/login.cgi", $data = "username=".$username."&passwd=".$passwd), true); 

      if($response["success"]){ 
       $send = true; 
      } 
      else { 
       $send = false; 
      } 
     echo $send; 
} 

的這裏的問題是,login.cgi頁應該設定該服務器的會話cookie,但使用PHP請求它只是不會。它會給出響應,但不會將cookie設置爲瀏覽器。你有什麼想法,我可以做什麼來模仿POST瀏覽器請求,並設置cookie,同時保持jQuery的功能?也許我應該設置一些標題? 如果將一個簡單的表格作爲「動作」,那麼login.cgi 會話cookie是,但用戶當然會留在那個頁面上,我無法更改,因爲我無法訪問它。

+0

您必須用四個空格縮進*每行*。 – Gumbo 2010-09-13 15:21:34

回答

1

使用stream_get_meta_data()來提取從服務器< - > synology請求返回的HTTP頭。如果代碼的其餘部分可以正確使用正確的synology urls/parameters,那麼從登錄請求返回的頭文件應該包含必要的會話cookie,以驗證Synology盒上的其他請求。

然後,您可以將其存儲在服務器<的用戶通信的會話文件中,並將其拖出以備後續請求。

評論隨訪:

是的,沒錯。 curl發起的請求完全是在服務器端完成的,根本不涉及客戶端。雖然您可以通過curl檢索synology會話/訪問cookie,但無法將該cookie發送給客戶端,以使其看起來像直接來自synology框。

例如,讓我們假裝在Synology響應餅乾頭看起來是這樣的:

Set-Cookie: sessionID=blahblahblah; path=/; domain=synologybox.com 

您提取會話ID,並將其轉發給客戶端:

setcookie("sessionID", 'blahblahblah', 360000, '/'); 

然後在客戶端將其存儲因爲來自yourserver.com,而不是synologybox.com。此外,您將無法設置通過的setcookie調用域:

setcookie("sessionID", 'blahblahblah', 360000, '/', 'synologybox.com') 

這是行不通的,因爲服務器< - >客戶端請求來自yourserver.com來了,這是遠不一樣synologbox.com

如果沒有任何訪問Synology框以攻擊額外的身份驗證設施,您很可能不得不構建整個代理版本的synology界面。

+0

是的服務器確實返回正確的cookie(使用stream_get_meta_data()檢查,但我不知道該怎麼辦!我仍然需要Cookie設置爲synology域。發送給客戶端在PHP中接收到的頭文件? – 2010-09-13 22:36:24

+0

當然,只需循環接收來自Synology框的頭文件並通過header()函數輸出它們,然後發送給客戶端。事實上客戶端會將Synology Cookie設置爲來自您的服務器,您無法讓客戶端設置該cookie,因此它看起來像來自Synology框,因爲它來自您的PHP腳本,它是一個併發症完全不同的機器/域。 – 2010-09-13 22:51:06

+0

我明白:(我讀的是,你可以接受cURL cookies,但我想你所說的「接受」並不意味着它將被設置爲來自Synology盒,我是對嗎? – 2010-09-13 22:59:34

0

如果您使用PHP進行此請求,那麼該Cookie將發送到您的服務器,而不是客戶端。您無法爲應用程序中的其他域設置Cookie,因此這不起作用。您需要堅持客戶端方法。

+0

有什麼建議嗎?如果我不能讓cookie設置遠程服務器比我沒有看到任何解決方案:( – 2010-09-13 16:31:48

+0

你不能讓所有必要的請求客戶端與Javascript? – Brad 2010-09-13 18:19:27

+0

不,因爲我不能提出請求通過JS到不同的域 – 2010-09-13 18:25:03