我正在为客户的网站开发一个应用程序。 这就是故事,该公司使用称为synology的应用程序/ HDD,它基本上是一个连接到互联网的硬盘盒,并通过预先创建的帐户向客户提供文件访问权限。 此接口是用CGI编写的,我无法访问该框(网站的网络和位置不同)。
我们想要做的是允许主网站(我正在建设)的登录表格绕过(至少向用户: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,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浏览器请求并在保持jquery功能的同时设置cookie?也许我应该设置一些标题? 如果将 login.cgi 的简单表单作为“action”作为“action”,那么会话cookie当然会保留在该页面上,因为我无法访问它,所以我无法更改。< / p>
答案 0 :(得分:1)
使用stream_get_meta_data()
提取从服务器返回的HTTP标头&lt; - &gt; synology请求。如果其余代码使用正确的synology urls /参数正常工作,则从登录请求返回的标头应包含在synology框中验证进一步请求所需的会话cookie。
然后,您可以将其存储在服务器&lt; - &gt;用户通信的会话文件中,并将其拖出以供后续请求使用。
评论后续:
是的,确切地说。 curl发起的请求完全是服务器端完成的,根本不涉及客户端。虽然您可以通过curl检索synology会话/访问cookie,但是无法将该cookie发送到客户端,使其看起来像是直接来自synology框。例如,让我们假装synology响应cookie标题如下所示:
Set-Cookie: sessionID=blahblahblah; path=/; domain=synologybox.com
您提取会话ID并将其转发给客户端:
setcookie("sessionID", 'blahblahblah', 360000, '/');
然后客户端会将其存储为来自yourserver.com
,而不是synologybox.com
。此外,您将无法通过setcookie调用设置域名:
setcookie("sessionID", 'blahblahblah', 360000, '/', 'synologybox.com')
这不起作用,因为服务器&lt; - &gt;客户端请求来自yourserver.com
,这与synologbox.com
差不多。
如果没有任何访问语法框来破解额外的身份验证设施,您很可能不得不构建整个代理版本的synology接口。
答案 1 :(得分:0)
如果您使用PHP发出此请求,则cookie将转到您的服务器,而不是客户端。您无法从应用程序为另一个域设置cookie,因此这不起作用。你需要坚持使用客户端方法。