#php #jquery #post #cookies
#php #jquery #Публикация #файлы cookie
Вопрос:
Я разрабатываю приложение для веб-сайта клиента. Вот история, эта компания использует приложение / жесткий диск под названием synology, которое в основном представляет собой жесткий диск, подключенный к Интернету, и предоставляет доступ к файлам клиентам с предварительно созданными учетными записями. Этот интерфейс написан на CGI, и у меня нет доступа к ящику (сеть и местоположение отличаются от веб-сайта).
Что мы хотим сделать, так это разрешить форму входа с основного веб-сайта (который я создаю) в обход (по крайней мере, для пользователей: D) формы входа в приложение.
Очевидно, что я не могу выполнить ajax-запрос jQuery к разным доменам, это не сработает. Итак, что я сделал, это
1) Форма на веб-сайте, работающем с jQuery:
$("#login_submit").click(function(){
var username= $("input#login_username").val();
var passwd= $("input#login_passwd").val();
var post_string = "username=" username "amp;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) Вызовите login.php страница отправки, передающая пользователя и пароль через POST, страница PHP отправляет HTTP-запрос POST на удаленный сервер synology и выдает мне ответ в формате JSON, по-видимому (?), который я преобразую в массив PHP, чтобы я мог видеть, является ли ключ «success» истинным или ложным,
если 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."amp;passwd=".$passwd), true);
if($response["success"]){
$send = true;
}
else {
$send = false;
}
echo $send;
}
Проблема здесь в том, что страница login.cgi должна устанавливать сессионный cookie для этого сервера, но при использовании этого PHP-запроса этого просто не произойдет. Он выдаст ответ, но не установит cookie в браузере. Есть ли у вас какие-либо идеи, что я могу сделать, чтобы имитировать запрос браузера POST и установить cookie, сохраняя при этом функцию jquery? может быть, мне следует установить несколько заголовков?
Если создать простую форму для этого login.cgi в качестве «действия», то сессионный cookie будет, но пользователь, конечно, останется на этой странице, которую я не могу изменить, поскольку у меня нет к ней доступа.
Комментарии:
1. Вы должны делать отступы в каждой строке с четырьмя пробелами.
Ответ №1:
Используйте stream_get_meta_data()
для извлечения HTTP-заголовков, возвращаемых с сервера<->synology requests. Если остальная часть вашего кода работает должным образом с соответствующими URL-адресами / параметрами synology, заголовки, возвращаемые из запроса на вход в систему, должны содержать сессионный cookie, необходимый для аутентификации дальнейших запросов в окне synology.
Затем вы можете сохранить это в файле сеанса для сервера<-> пользовательские сообщения и извлекать его для последующих запросов.
последующие комментарии:
да, именно. Запросы, инициируемые curl, выполняются исключительно на стороне сервера и вообще не будут привлекать клиента. Хотя вы МОЖЕТЕ получить файл cookie сеанса synology / доступа через curl, нет способа отправить этот файл cookie клиенту так, чтобы он выглядел так, как будто он был получен непосредственно из окна synology.
Например, давайте представим, что заголовок cookie-файла synology response выглядит следующим образом:
Set-Cookie: sessionID=blahblahblah; path=/; domain=synologybox.com
Вы извлекаете идентификатор сеанса и пересылаете его клиенту:
setcookie("sessionID", 'blahblahblah', 360000, '/');
тогда клиент сохранит это как исходящее от yourserver.com
, а не synologybox.com
. Кроме того, вы не смогли бы установить домен с помощью вызова setcookie:
setcookie("sessionID", 'blahblahblah', 360000, '/', 'synologybox.com')
Это не сработает, так как от сервера поступает запрос<->client yourserver.com
, который и близко не совпадает с synologbox.com
.
Без какого-либо доступа к synology box для взлома дополнительных средств аутентификации вам, скорее всего, придется создавать целую прокси-версию интерфейса synology.
Комментарии:
1. да, сервер возвращает правильный cookie (проверено с помощью stream_get_meta_data(), но я не знаю, что с ним делать! Мне все еще нужно, чтобы cookie был установлен для домена synology. Нет ли способа отправить клиенту заголовок, полученный на PHP?
2. Конечно, просто перебирайте заголовки, полученные из окна synology, и выводите их с помощью
header()
функции, чтобы они отправлялись клиенту. Но тогда вы все еще сталкиваетесь с тем фактом, что клиент установит файл cookie synology как полученный с вашего сервера. Вы никак не можете заставить клиента установить этот cookie, чтобы он выглядел так, как будто он был получен из окна synology, поскольку он поступает из вашего PHP-скрипта, который является совершенно другим компьютером / доменом.3. Я понимаю: (я читал, что вы можете принимать cookie-файлы с помощью cURL, но я полагаю, из того, что вы говорите, что «принять» не означает, что оно будет установлено как исходящее из окна synology, я прав?
4. Большое спасибо, Марк Би! Вы получили оценку за лучший ответ 🙂 Лучшая поддержка за всю историю 🙂 Я запросил доступ к synology box. еще раз спасибо
5. вам необходимо пройти аутентификацию в /usr/syno/synoman/webman/modules/authenticate.cgi и использовать этот cookie в дальнейшем.
Ответ №2:
Если вы делаете этот запрос на PHP, то cookie отправляется на ваш сервер, а не клиенту. Вы не можете установить cookie для другого домена из своего приложения, поэтому это не сработает. Вам нужно придерживаться метода на стороне клиента.
Комментарии:
1. есть предложения? если я не могу разрешить установку cookie удаленным сервером, я не вижу никакого решения: (
2. Разве вы не можете выполнить все необходимые запросы на стороне клиента с помощью Javascript?
3. Нет, потому что я не могу отправлять запросы через JS в разные домены