Использование cURL для авторизации...

can2

Новичок
Использование cURL для авторизации...

Здравствуйте,
Пытаюсь написать парсер для корпоративной мэил системы (написана на перле). Но столкнулся с проблемой авторизации php скрипта на сервере мэйлера.

Есть вот такой код:

PHP:
// Сперва на сервере используется HTTP Basic авторизация, выполняем ее:
$url = "http://example.ru";
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERPWD, "login : password");
$result = curl_exec($ch);
curl_close($ch);
echo $result;

//В случае удачной авторизации выводится веб-форма, куда нужно забить следующую пару логин/пароль

$login      = 'login';
$password   = 'password';
$login_url         = 'http://example.ru/login.pl';
$login_var_name    = 'login';
$password_var_name = 'password';
$user_cookie_file = $_SERVER['DOCUMENT_ROOT'].'/cookie.txt';
$user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; (R1 1.5))";

if (!$ch1 = curl_init())
{
    echo curl_error($ch1);
    exit;
}  
$post_fields = "$login_var_name=$login&$password_var_name=$password";

curl_setopt($ch1, CURLOPT_URL, $login_url);   
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch1, CURLOPT_VERBOSE, 1);
curl_setopt($ch1, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch1, CURLOPT_USERAGENT, $user_agent);
curl_setopt($ch1, CURLOPT_REFERER,   'example.ru');
curl_setopt($ch1, CURLOPT_COOKIEFILE, $user_cookie_file);
curl_setopt($ch1, CURLOPT_COOKIEJAR,  $user_cookie_file); 
curl_setopt($ch1, CURLOPT_POST, 1);
curl_setopt($ch1, CURLOPT_POSTFIELDS, $post_fields);

$content = curl_exec($ch1);
curl_close($ch1);
echo $content;
В итоге выходит страница:
Authorization Required
This server could not verify that you are authorized to access the document requested. Either you supplied the wrong credentials (e.g., bad password), or your browser doesn't understand how to supply the credentials required.
А затем снова та же веб-форма для второй части авторизации.

Пробовал использовать вторую часть скрипта для авторизации через вебформу на других сайтах, все работает. А вот вместе эти авторизации не пашут.

Подскажите пожалуйста, в чем может быть проблема.

Заранее благодарю.
 

fixxxer

К.О.
Партнер клуба
А ты уверен что там basic авторизация а не какой нибудь digest?
Смотри какими заголовками обменивается браузер с сервером, любым http сниффером. Потом повтори так, чтобы скрипт делал так же. Если не получается с курлом, делай черех fsockopen.
 

can2

Новичок
Да, авторизация basic. А разве есть разница, если первый этап авторизации у меня проходит успешно? А вот второй, где используются куки - не работает...

Вот, изменил вторую часть:
PHP:
$ch1 = curl_init("http://example.ru/login.pl");
curl_setopt($ch1, CURLOPT_VERBOSE, 2); 
curl_setopt($ch1, CURLOPT_ENCODING, 0); 
curl_setopt($ch1, CURLOPT_USERAGENT, 'Mozilla/5.0'); 
curl_setopt($ch1, CURLOPT_COOKIEFILE, $_SERVER['DOCUMENT_ROOT'].'/cookie.txt'); 
curl_setopt($ch1, CURLOPT_COOKIEJAR, $_SERVER['DOCUMENT_ROOT'].'/cookie.txt');
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch1, CURLOPT_FAILONERROR, 1);
curl_setopt($ch1, CURLOPT_HEADER, 1);
curl_setopt($ch1, CURLINFO_HEADER_OUT, 1);
curl_setopt($ch1, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch1, CURLOPT_COOKIE, "cookie1=1;cookie2=2"); 
curl_setopt($ch1, CURLOPT_POSTFIELDS, "login=login&password=password");
$result_2 = curl_exec($ch1);
echo "Result:\n\n";
echo $result_2;
curl_close($ch1);
Эффекта ноль. Переменная $result_2 абсолютно пуста.

В чем проблема, не понимаю... Даже если просто ввести в строке браузера "http://тотсамыйсайт.ru/login.pl?login=login&password=password", то само сабой все работает, куки создаются, авторизация проходит успешно...

В общем, я с http заголовками и курлом знаком слабо, а с fsockopen и подавно =)
Посоветуйте, что еще можно сделать, или направьте на пример использования fsockopen для аналогичного случая.

Спасибо.
 

whirlwind

TDD infected, paranoid
может в этом дело

PHP:
curl_setopt($ch, CURLOPT_USERPWD, "login : password"); 
                                        ^ ^
приводить надо тот код, который не работает
 

can2

Новичок
Нет, тут все нормально, пробелы я поставил из-за того, что ":" и "p" у вас тут в смайлик превращается:
PHP:
curl_setopt($ch, CURLOPT_USERPWD, "login:password");
К тому же первая часть работает, а не работает вторая.
 

shark_255

Новичок
юзай отладку curl-овскую - это раз

PHP:
$fp_err = fopen($_SERVER['DOCUMENT_ROOT'].'/verbose_file.txt', 'ab+');
fwrite($fp_err, date('Y-m-d H:i:s')."\n\n"); //add timestamp to the verbose log	             
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_STDERR, $fp_err);
а во вторых авторизация может проходить в несколько этапов - почитай документацию
 

George

Новичок
Ребята, очень прошу помощи по этому же вопросу. Замучался очень ...
Направте на путь праведный, что я делаю не так? Первый раз пробую авторизовацться средствами PHP...

Вот такое общение происходит, если я входу руками (ниже).
Взято из 'Live HTTP Headers' плагина для Firefox.
Я заменил только GET ... , HOST: ... , username и password.
Очень нежелательно чтобы эти данные вылезли где-то в кешах гугл )

Код:
GET /somefolder/filename.php HTTP/1.1
Host: sub.domain.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

HTTP/1.x 401 Unauthorized
Date: Fri, 29 May 2009 19:02:06 GMT
Server: Apache/2.2.11 (Unix) PHP/5.2.9
X-Powered-By: PHP/5.2.9
Set-Cookie: PHPSESSID=bdc1ff5a452601a65b2a28e04d22faa9; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
WWW-Authenticate: Basic realm="Введите имя пользователя и пароль"
Content-Length: 53
Connection: close
Content-Type: text/html
----------------------------------------------------------

GET /somefolder/filename.php HTTP/1.1
Host: sub.domain.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Authorization: Basic MDczODk2OjA3Mzg5NjA3Mzg5Ng==
Cookie: PHPSESSID=bdc1ff5a452601a65b2a28e04d22faa9

HTTP/1.x 200 OK
Date: Fri, 29 May 2009 19:03:40 GMT
Server: Apache/2.2.11 (Unix) PHP/5.2.9
X-Powered-By: PHP/5.2.9
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 2892
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

и каким только методом не пробовал авторизоваться..

и с помощью передачи resource $context, как параметр в fopen:
PHP:
$protocol = "http://";
$url = "sub.domain.com/somefolder/filename.php";
$username = "username";
$password = "12345";
$cred = sprintf('Authorization: Basic %s',base64_encode("$username:$password") );
$opts = array('http'=>array('method'=>'POST','header'=>$cred));
$ctx = stream_context_create($opts);
$handle = fopen ( $protocol.$url, 'r', false,$ctx);
$content = fread($handle,1000000);
и с помощью fsockopen:
PHP:
$fp = pfsockopen ("sub.domain.com", 80);
$request = "GET /somefolder/filename.php HTTP/1.1";
$request .= "Host: sub.domain.com";
$request .= "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10";
$request .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
$request .= "Accept-Language: en-gb,en;q=0.5";
$request .= "Accept-Encoding: gzip,deflate";
$request .= "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7";
$request .= "Keep-Alive: 300";
$request .= "Connection: keep-alive";
$request .= "Authorization: Basic MDczODk2OjA3Mzg5NjA3Mzg5Ng==";
fwrite ($fp, $request);
while ($line = fgets ($fp, 1024))
	{
	echo $line;
	}

и с помощью cURL:
PHP:
$curl_conn = curl_init();

curl_setopt($curl_conn, CURLOPT_URL, "http://sub.domain.com/somefolder/filename.php");
curl_setopt($curl_conn, CURLOPT_CRLF, true);
curl_setopt($curl_conn, CURLOPT_GET, true);
curl_setopt($curl_conn, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl_conn, CURLOPT_USERPWD, 'username:12345');
curl_setopt($curl_conn, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl_conn, CURLOPT_RETURNTRANSFER, true);

$output = curl_exec($curl_conn);

curl_close($curl_conn);

echo $output;
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
>очень прошу помощи по этому же вопросу. Замучался очень ...

настроить на корпоративном сервере POP3/IMAP и забить на парсинг
 

George

Новичок
Автор оригинала: grigori
>очень прошу помощи по этому же вопросу. Замучался очень ...

настроить на корпоративном сервере POP3/IMAP и забить на парсинг
остроумно ;-)

всем спасибо.. помучавшись еще денек я во всем сам разобрался. Помог замечательный класс Snoopy http://sourceforge.net/projects/snoopy/.
Получилось вот так:
PHP:
	include "Snoopy/Snoopy.class.php";
	$snoopy = new Snoopy;
	$snoopy->host = "http://sub.domain.com/somefolder/file.php";
	$snoopy->user = "username";
	$snoopy->pass = "12345";

	
if(!isset($_GET['cookie_id']))
	{
	$snoopy->fetch($snoopy->host);
	$cookie_id = substr($snoopy->headers[4], 22, -10);
	header('Location: http://localhost/snoopy.php?cookie_id='.$cookie_id);
	}
else
	{
	$snoopy->cookies['PHPSESSID'] = $_GET['cookie_id'];
	$snoopy->fetch($snoopy->host);
	print $snoopy->results;
	}
короче - куку нужно было еще вложить к HTTP-посылке :)
 

AmdY

Пью пиво
Команда форума
George
поздравляю, а если поищешь на форуме, найдёшь класс от grigori, он будет позамечательнее, в примерах есть как с куками работать
 
Сверху