Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Экзамен / web / example1 / Введение в PHP.doc
Скачиваний:
101
Добавлен:
18.05.2015
Размер:
3 Mб
Скачать

Http идентификация с php

HTTP идентификация в PHP возможна только в том случае, когда PHP выполняется как модуль Apache и невозможна для версии CGI. В модуле PHP возможно использовать функцию header() чтобы послать "Authentication Required" сообщение клиентскому браузеру для использования в окне Username/Password. Если пользователь заполнил логин/пароль, URL содержащее PHP script будет вызвано вновь с предопределенными переменными PHP_AUTH_USER, PHP_AUTH_PW, and AUTH_TYPE установленными в user name, password and authentication type соответственно. Эти предопределенные переменные находятся в массивах $_SERVER и $HTTP_SERVER_VARS. Поддерживаются оба метода авторизации "Basic" и "Digest" .

Пример скрипта вынуждающего клиента пройти аутентикацию следующий:

<?php

if (!isset($_SERVER['PHP_AUTH_USER'])) {

header('WWW-Authenticate: Basic realm="My Realm"');

header('HTTP/1.0 401 Unauthorized');

echo 'Text to send if user hits Cancel button';

exit;

} else {

echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";

echo "<p>You entered {$_SERVER['PHP_AUTH_PW']} as your password.</p>";

}

?>

В следующем примере показано как использовать простой “Digest” идентификационный скрипт.

<?php

$realm = 'Restricted area';

//user => password

$users = array('admin' => 'mypass', 'guest' => 'guest');

if (empty($_SERVER['PHP_AUTH_DIGEST'])) {

header('HTTP/1.1 401 Unauthorized');

header('WWW-Authenticate: Digest realm="'.$realm.

'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');

die('Text to send if user hits Cancel button');

}

// analyze the PHP_AUTH_DIGEST variable

if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) ||

!isset($users[$data['username']]))

die('Wrong Credentials!');

// generate the valid response

$A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]);

$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);

$valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);

if ($data['response'] != $valid_response)

die('Wrong Credentials!');

// ok, valid username & password

echo 'Your are logged in as: ' . $data['username'];

// function to parse the http auth header

function http_digest_parse($txt)

{

// protect against missing data

$needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);

$data = array();

$keys = implode('|', array_keys($needed_parts));

preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);

foreach ($matches as $m) {

$data[$m[1]] = $m[3] ? $m[3] : $m[4];

unset($needed_parts[$m[1]]);

}

return $needed_parts ? false : $data;

}

?>

Будьте внимательны, используя HTTP заголовки. Чтобы гарантировать максимальную совместимость со всеми клиентами ключевое слово "Basic" должно начинаться с прописной буквы "B", и строка realm должна помещаться в двойные (не ординарные ) ковычки, и точно один пробел должен предшествовать коду 401 в HTTP/1.0 401 строке заголовка.

Вместо простой печати PHP_AUTH_USER and PHP_AUTH_PW, как сделано в примере вы можете проверить логин и пароль на законность. Может быть использован запрос к базе данных или файлу.

Для авторизации можно использовать $_SERVER['REMOTE_USER'].

Очистить кэш окна браузера можно получением от сервера ответа 401. Это равносильно "log out" .

Пример стимуляции нового имени/пароля

<?php

function authenticate() {

header('WWW-Authenticate: Basic realm="Test Authentication System"');

header('HTTP/1.0 401 Unauthorized');

echo "You must enter a valid login ID and password to access this resource\n";

exit;

}

if (!isset($_SERVER['PHP_AUTH_USER']) ||

($_POST['SeenBefore'] == 1 && $_POST['OldAuth'] == $_SERVER['PHP_AUTH_USER'])) {

authenticate();

} else {

echo "<p>Welcome: {$_SERVER['PHP_AUTH_USER']}<br />";

echo "Old: {$_REQUEST['OldAuth']}";

echo "<form action='{$_SERVER['PHP_SELF']}' METHOD='post'>\n";

echo "<input type='hidden' name='SeenBefore' value='1' />\n";

echo "<input type='hidden' name='OldAuth' value='{$_SERVER['PHP_AUTH_USER']}' />\n";

echo "<input type='submit' value='Re Authenticate' />\n";

echo "</form></p>\n";

}

?>

void header ( string $string [, bool $replace = true [, int $http_response_code ]] )

Функция header() используется, чтобы послать заголовок HTTP и должена быть вызвана раньше любого другого вывода.

<html>

<?php

/* This will give an error. Note the output

* above, which is before the header() call */

header('Location: http://www.example.com/');

?>

Возможны два способа вызова функции header(). В первом header() стартует со строкой "HTTP/" (case is not significant), и может использоваться, чтобы переслать код статуса HTTP. Например

<?php

header("HTTP/1.0 404 Not Found");

?>

Код 404 пересылается в случае ошибки поиска файла

Во втором случае header() содержит строку "Location:". В этом случае header () не только возвращает назад на броузер, но возвращает также REDIRECT (302) код статуса.

<?php

header("Location: http://www.example.com/"); /* Redirect browser */

/* Make sure that code below does not get executed when we redirect. */

exit;

?>

Рассмотрим пример выдачи html и обработки ее - заменить ссылки на свои. Данные передаются по методу POST из формы.

<?php

$hostname = "localhost";

$path = "/obrabotka.php"; 

$line = "";

// Устанавливаем соединение, имя которого

// передано в параметре $hostname

$fp = fsockopen($hostname, 80, $errno, $errstr, 30);

// Проверяем успешность установки соединения

if (!$fp) echo "$errstr ($errno)<br />\n";

else

{

// Данные HTTP-запрос

$data =

"n=".urlencode("Значение перменной")."\r\n\r\n";

// Заголовок HTTP-запроса

$headers = "POST $path HTTP/1.1\r\n";

$headers .= "Host: $hostname\r\n";

$headers .= "Content-type: application/x-www-form-urlencoded\r\n";

$headers .= "Content-Length: ".strlen($data)."\r\n\r\n";

// Отправляем HTTP-запрос серверу

fwrite($fp, $headers.$data);

// Получаем ответ

while (!feof($fp))

{

$line .= fgets($fp, 1024);

}

fclose($fp);

}

echo $line;

?>

Соседние файлы в папке example1