Как сделать вход на сайт по паролю php
Перейти к содержимому

Как сделать вход на сайт по паролю php

  • автор:

Пароль на страницу

Я решил описать способы закрыть паролем часть сайта. Тема, на самом деле, большая, поэтому на первый раз ограничусь авторизацией php+mysql.

Самый первый вопрос, который обычно встаёт — как закрыть директорию со скрпитами администрирования паролем. При этом не нужно никаких изысков — один или несколько администраторов имеют одни и те же права, а персоналии меняются редко. Проще всего в данной ситуации использовать стандартную серверную авторизацию — положить файлы .htaccess и .htpasswd и прописать в них нужные параметры. Про это уже написано много, поэтому я ничего особо нового не скажу, лучше посмотрите сюда.

Добавлю две вещи. Первое — это куда класть файл .htpasswd. Экспериментальным путем я выяснил, что если, например, путь к документу с сообщением об ошибке (ErrorDocument) пишется относительно системной переменной DocumentRoot. Но путь к файлу с паролями (UserFile) пишется относительно ServerRoot. Насколько я понял, выше ServerRoot положить .htpasswd нельзя — «../» не воспринимается. Всё это сделано для того, чтобы можно было поместить файл с паролями, например, одним уровнем выше корневой директории сайта, чтобы из сети доступа к файлу не было вообще.

Второе — это то, что скрипт может узнать, кто его открывает и пароль: переменные $PHP_AUTH_USER и $PHP_AUTH_PW.

Главный недостаток этого способа — сервер не может блокировать подбор пароля (это после нескольких неудачных попыток входа пользователю предлагается подождать часок-другой, а в течение этого времени обращения с его IP-адреса игнорируются). Это написано в официальной документации по Апачу.

Ещё один недостаток — необходимость переписывать файлы с паролями при удалении пользователя или введении нового. Но если это происходит нечасто, этого способа вполне достаточно, к тому же не придётся забивать голову написанием механизма авторизации.

Это нужно не только для упрощения работы с большим количеством пользователей и их большой «текучкой». Если нужно держать дополнительную информацию о пользователях, либо необходимо гибкое разграничение прав, лучше перенести авторизацию в базу.

Каждая страница закрытой территории подключает файл с вот таким кодом:

$result = mysql_query(" SELECT * FROM person WHERE login='". preg_replace("/[^\\w_-]/","",$PHP_AUTH_USER). "' AND pass='". md5($PHP_AUTH_PW). "'"); if (@mysql_num_rows($result)!=1) < header("WWW-Authenticate: Basic realm=\"User area\""); header("HTTP/1.0 401 Unauthorized"); print("Чтобы войти в пользовательскую часть сайта, надо ввести имя и пароль."); exit(); >; $user_row = mysql_fetch_array($result);

В первой строке из логина удаляются все символы кроме букв, цифр, тире и символа подчеркивания. Затем проверяется количество полученных строк, и только если это одна строка, дается доступ. В остальных случаях пользователь увидит в броузере окно, предлагающее ввести логин и пароль. Если же пользователь вошел успешно, в массиве $user_row мы имеем всю информацию о нем.

Конечно же, пример, который я привёл, имеет ряд существенных недостатков. Не переписывайте его один-в-один, чтобы потом не пасть жертвой попыток подбора пароля, потому что

  • защиты от подбора здесь нет
  • если таблица пользователей большая, при подборе пароля злоумышленник, скорее всего, «завалит» базу

И последний на сегодня способ — хранение зашифрованных данных в куках.

Есть скрипт для входа, остальные подключают код, позволяющий только продолжить действия в закрытой области — если куки истекут, или он выйдет оттуда, придётся возвращаться на страницу для входа.

Входной скрипт проверяет логин и пароль и выдает две куки. В первой — логин, чтобы сразу опознать пользователя (в базе поле логина, естественно, уникальное или даже ключевое). Во второй куке — хэш от времени входа и пароля (для полноты конспирации я добавляю к этим строкам букву «Ы» — тогда хэш подобрать почти невозможно :).

Все остальные программы подключают код, который делает следующее. Делает запрос в базу — выбирает строку с полученным логином. Из этой строки берет поле «log_time» и пароль и делает из них, как и описано выше, хэш. Сравнивает его с тем, что получил, и если они совпадают, выдает новую куку хэша, опять же, от пароля, времени и буквы «Ы» и делает запрос в базу данных «UPDATE user SET log_time=’. ‘ WHERE login=’$cookie_login'».

if (isset($HTTP_COOKIE_VARS[$cookie_login]) && isset($HTTP_COOKIE_VARS[$cookie_code])) < $login = $HTTP_COOKIE_VARS[$cookie_login]; $code = $HTTP_COOKIE_VARS[$cookie_code]; $result = mysql_query("SELECT date_format(log_date,'%Y%m%d%H%i%s') as log_date1, pass,uid FROM user WHERE email='$login' AND log_date>'DATE_SUB(NOW(),INTERVAL 15 MINUTE)'"); if (!mysql_error() && @mysql_num_rows($result)==1) < $log_time0 = time(); $log_time1 = date("YmdHis", $log_time0); $log_time2 = date("Y-m-d H:i:s", $log_time0); $current_user = mysql_fetch_array($result); if (md5($current_user["pass"].$current_user["log_date1"].$md5letter) == $code) < mysql_query("UPDATE user SET log_date='$log_time2' WHERE uid=".$current_user["uid"]); setcookie($cookie_code, md5($current_user["pass"].$log_time1.$md5letter), time()+900, $site_path); $auth = true; >else unset($current_user); >; >;

Опять же, здесь нет никакой защиты от подбора и атаки на сервер (кстати, здесь можно вместо буквы «Ы» писать IP-адрес пользователя — чтобы, например, соседу по офису нельзя было взять файл с кукой и зайти со своего компьютера).

Пароль на страницу. Часть 2. Блокировка подбора

Когда я выложил этот выпуск в прошлый раз, меня запинали на месте, мол такой блокировкой можно и сервер «пустить под откос».

Но сначала о блокировке подбора. Банальности, но всё-таки. Пароль длинной десять символов из букв латиницы и цифр — это очень много вариантов. Если подбирать пароль по 1 000 000 вариантов в секунду, понадобится несколько тысяч лет. Но поскольку такую абракадабру запомнить сложно, мы чаще делаем пароль из осмысленных слов. Несколько лет назад оказалось, что большинство паролей можно подобрать при помощи словаря из 10 000 слов. В своё время в сети появился червь (вирус такой), который лазил по юниксовым серверам, используя их дырки в защите, и подбирал пароли привелигированых пользователей при помощи. системного орфографического словаря Юникса. Ничего таскать не надо было!

Каждый пользователь, пока он не ввёл правильный логин и пароль, считается злобным хакером. С чем же мы имеем дело, когда пользователь вводит что-либо неправильно?

  • забывчивость (на это на приличных сайтах есть формочка «забыл пароль», чтобы отправить на введёный в системных настройках email этот самый пароль)
  • баловство («ибо нефиг»)
  • подбор пароля по словарю (вероятность удачного подбора велика, поэтому закрывать надо, тем более, если сайт коммерческого характера)
  • DoS-атака (чтобы не перегрузить сервер, надо минимизировать действия, которые будет выполнять скрипт в таком случае)

Я долго думал, как можно вызвать перегрузку на сервере, если механизм защиты стоит на файлах. Оказалось, несложно (сколько это будет стоить — другой вопрос). Итак, допустим, сервер не выдержит, если скрипт будет пытаться 1000 раз в секунду открывать файлы на запись и писать в них данные. Поскольку после 5 неудачных попыток войти в систему пользователь будет сразу получать отказ в доступе (без какой-либо записи данных в файл), надо найти 200 уникальных IP, с которых по пять раз и обратиться. Это возможно. Вешаем в баннерокрутилке html-баннер с пятью тегами:

  

Пользователь моментально делает пять обращений сервер пять раз пишет в файл (кстати, в некоторых броузерах, возможно, выскочит окно для ввода логина и пароля). Можно сделать html-страницу с пятью такими картинками, а саму страницу вставить через iframe на посещаемый сайт (через iframe — чтобы по полю referer не нашли. Вряд ли служба поддержки халявного хостинга будет заниматься такими вещами как копание в лог-файлах в поисках рефереров). Те примеры, которые я привёл, разумеется, натянуты, но сам факт того, что можно воспользоваться таким недостатком системы, доказан. Кстати, нечто подобное уже было.

Но всё-таки приведу этот способ — зря писал, что ли? Его, кстати, можно без особого страха применять для ограниченного количества адресов (например, для локальной сети фирмы), положив в директорию файл .htaccess такого содержания:

order deny,allow deny from all allow from xxx.xxx.xxx

А вот код программы:

$errors = 0; $fn = "ignore/". preg_replace("[^\d\.]", "", $REMOTE_ADDR. ". ". $HTTP_FORWARDED_FOR); if (is_file($fn)) < if (filectime($fn) < time()-3600) unlink($fn); >else $errors = fread(fopen($fn, "r"), 2); if ($errors>5) < print ("Доступ закрыт. Зайдите через час."); exit(); >; // здесь происходит установка связи с сервером БД. // чтобы не трогать зря, если пользователя сразу же "отлупили". $result = mysql_query("SELECT * FROM user WHERE login='". preg_replace("/[^\w_\-]/", "", $PHP_AUTH_USER). "' AND pass='". md5($PHP_AUTH_PW). "'"); if (@mysql_num_rows($result)!=1) < header("WWW-Authenticate: Basic realm=\"secret area\""); header("HTTP/1.0 401 Unauthorized"); print ("Authorization required"); fwrite(fopen($fn, "w"), ++$errors); exit(); >; $current_user = mysql_fetch_array($result); mysql_free_result($result);

Впрочем, грех работать с файлами, если есть база. Шутка. Для не прошедших авторизации создаём таблицу:

CREATE TABLE unauth (username VARCHAR(64) NOT NULL, pass VARCHAR(64) NOT NULL, ip VARCHAR(255), logintime TIMESTAMP)

И вместо обращения к файлам работаем с базой.

$errors = @mysql_result(mysql_query("SELECT count(username) as falses FROM unauth WHERE logintime>DATE_SUB(NOW(),INTERVAL 1 HOUR) AND ip='$REMOTE_ADDR'"),0); if (mysql_error()) die(mysql_error()); if ($errors>5) < print ("Доступ закрыт. Зайдите через час."); exit(); >; $result = mysql_query("SELECT * FROM user WHERE login='". preg_replace("/[^\w_\-]/", "", $PHP_AUTH_USER). "' AND pass='". md5($PHP_AUTH_PW). "'"); if (@mysql_num_rows($result)!=1) < header("WWW-Authenticate: Basic realm=\"secret area\""); header("HTTP/1.0 401 Unauthorized"); print ("Authorization required"); mysql_query("INSERT INTO unauth (username, pass, ip) VALUES ('$PHP_AUTH_USER', '$PHP_AUTH_PW', '$REMOTE_ADDR $HTTP_X_FORWARDED_FOR')"); exit(); >; $current_user = mysql_fetch_array($result); mysql_free_result($result);

Хранить ли старые записи для статистики или нет — дело хозяйское. Если что, их можно удалять, выполняя перед авторизацией запрос:

DELETE FROM unauth WHERE logintime

Такой механизм при больших нагрузках будет работать быстрее и надёжнее, чем файлы - в базе часто используемые данные буферизуются и обрабатываются непосредственно в оперативной памяти.

Пароль на страницу. Часть 3. Пароль от базы

Была у меня в своё время проблема: надо закрыть администрационную часть сайта, но при этом я не могу положить файл .htpasswd выше корневой директории сайта. Врождённая подозрительность не позволяла положить файл с паролем и отдельную директорию и заблокировать доступ к ней по http. Решил попробовать сделать защиту как в phpMyAdmin: у пользователя спрашиваются логин и пароль, с которыми скрипт соединяется с базой. В своём анализаторе логов я сделал именно так. Удобство метода в том, что файл можно складывать куда угодно - никаких кук, никаких директив сервера для директории. Заодно, если поменяется пароль в базе данных, не надо ничего исправлять в скрипте.

Распишу метод на примере MySQL. Пишем функцию, например, mysql_die:

function mysql_die() < header("HTTP/1.0 401 Unauthorized"); header("WWW-authenticate: basic realm=\"Statistics\""); print ("Access denied. User name and password required."); exit(); >

В начале программы указываются хост сервера БД и, если надо, имя базы:

$db_host = "localhost"; $db_name = "somedatabase";

А для соединения с базой берутся переменные сервера: $PHP_AUTH_USER и $PHP_AUTH_PW.

$db_connect = @mysql_connect($db_host, $PHP_AUH_USER, $PHP_AUTH_PW) or mysql_die();

И всё. Теперь о недостатках. Разумеется, с такой защитой можно пробовать подбирать пароль (в принципе, можно приделать блокировку, но тогда потеряется вся красота метода). Пароль, как и в случае защитой средствами сервера, пересылается в открытом виде. Но для простых задач такое вполне сгодится.

Как настроить авторизацию через социальные сети на сайте

Настройте авторизацию через социальные сети на вашем сайте с помощью нашего пошагового руководства и примера для Google на PHP!

Person connecting with social media accounts for website authorization

Алексей Кодов
Автор статьи
1 июня 2023 в 13:31

Авторизация через социальные сети стала неотъемлемой частью современных сайтов и приложений. Она позволяет пользователям быстро входить на сайт, используя свои учетные записи в социальных сетях, без необходимости запоминать еще один логин и пароль. В этой статье мы рассмотрим, как настроить авторизацию через социальные сети на вашем сайте.

Шаг 1: Выбор социальных сетей для авторизации

Прежде всего, определитесь, через какие социальные сети вы хотите предоставить возможность авторизации на вашем сайте. Самые популярные варианты – это Facebook, Google, Twitter и VKontakte.

Шаг 2: Регистрация приложения в социальной сети

Для каждой из выбранных социальных сетей вам нужно создать приложение, которое будет использоваться для авторизации на вашем сайте.

Процесс регистрации приложения может немного отличаться в зависимости от социальной сети, но в основном вам потребуется указать:

  • Название приложения
  • URL-адрес сайта
  • URL-адрес обратного вызова (callback)

После успешной регистрации приложения, вам будут предоставлены уникальные ключи (Client ID и Client Secret), которые потребуются для настройки авторизации на вашем сайте.

Шаг 3: Интеграция авторизации на сайте

На этом этапе вам необходимо интегрировать авторизацию через социальные сети на вашем сайте. Это можно сделать с помощью специализированных библиотек и плагинов для вашего стека технологий или написать собственную реализацию.

Важно помнить, что для безопасности процесса авторизации следует использовать протокол OAuth 2.0. Он предоставляет надежный механизм авторизации, не требуя передачи пароля пользователя вашему сайту.

Веб-разработчик: новая работа через 9 месяцев
Получится, даже если у вас нет опыта в IT

Пример: Авторизация через Google на сайте на PHP

Для настройки авторизации через Google на сайте с использованием PHP можно воспользоваться библиотекой Google API Client Library for PHP.

  1. Установите библиотеку с помощью Composer:
composer require google/apiclient 
  1. Создайте файл config.php с данными вашего приложения:
<?php $clientID = 'YOUR_CLIENT_ID'; $clientSecret = 'YOUR_CLIENT_SECRET'; $redirectUri = 'YOUR_REDIRECT_URI';
  1. В файле index.php добавьте код для авторизации:
<?php require_once 'vendor/autoload.php'; require_once 'config.php'; $client = new Google_Client(); $client->setClientId($clientID); $client->setClientSecret($clientSecret); $client->setRedirectUri($redirectUri); $client->addScope("email"); $client->addScope("profile"); // Обработка авторизации и получение информации о пользователе if (isset($_GET['code'])) < $token = $client->fetchAccessTokenWithAuthCode($_GET['code']); $client->setAccessToken($token['access_token']); $google_oauth = new Google_Service_Oauth2($client); $google_account_info = $google_oauth->userinfo->get(); $email = $google_account_info->email; $name = $google_account_info->name; // Здесь можно обработать данные пользователя и авторизовать его на вашем сайте >
  1. На странице авторизации добавьте кнопку для входа через Google:

Теперь пользователи смогут авторизоваться на вашем сайте через свои аккаунты Google. Аналогичным образом можно настроить авторизацию через другие социальные сети.

�� Удачи в настройке авторизации через социальные сети на вашем сайте! Если вы хотите углубить свои знания в веб-разработке и научиться создавать качественные сайты и приложения, рекомендую обратить внимание на эту школу:

Как сделать вход на сайт по паролю php

Автор : Орлов . Статья по ходу древняя

Глава 8. PHP: авторизация доступа

Если вы хотя бы иногда посещаете сайты, на которых есть "защи-щенная зона" — часть, доступ на которую возможен лишь по опреде-ленным логину и паролю (например, почтовые службы с web-интерфейсом или сервисы хостинга), то вас наверняка интересовало, как все-таки вся эта авторизация происходит. И наверняка вам хоте-лось устроить то же самое и на вашем сайте — ведь необходимость в этом иногда возникает. Ниже будет рассказано о технологиях автори-зации доступа, основанных на средствах web-сервера и технологии PHP.

Думается, значение слова "авторизация" вам понятно — это не что иное, как обеспечение возможности доступа к чему-либо тем и только тем пользователям, которые знают определенные кодовые слова — ло-гин и пароль.

Авторизация средствами web-сервера

Для того, чтобы к файлам, находящимся в какой-либо директории, могли иметь доступ лишь определенные посетители, знающие два ко-довых слова — логин и пароль, можно использовать встроенные в Web-сервер Apache средства ограничения доступа.

В конфигурационном файле Apache (он именуется httpd.conf, а просматривать и редактировать его могут только администраторы web-сервера) есть специальная строчка — AccessFileName. Там указано имя, найдя файл с которым в той или иной папке, Apache выполнит по отношению к ней указания, содержащиеся в нем. По традиции это имя — .htaccess, и именно таким оно установлено на всех серверах хос-тинга. В файл .htaccess можно поместить команды ограничения дос-тупа к той папке, в которой это файл находится.

Выглядят эти команды так. Вначале указывается название защи-щенной зоны — AuthName. Именно это название будет впоследствии выводиться в запросе посетителю (рис.8.1).

AuthName "Private Zone" AuthType Basic

В следующем параметре — AuthUserFile — указывается путь к файлу с логинами и паролями посетителей. Этот файл должен быть создан в особом формате, так как пароли в нем хранятся в зашифрованном ви-де. Для создания файлов с паролями применяются специальные про-граммы — такую программу вы можете взять, например, в разделе тех-нической поддержки компании Valuehost по адресу http://support.valuehost.ru/bbs/files/69-htpasswd.exe. Запускать ее следу-ет из командной строки в формате

69-htpasswd.exe -c имя_файла_паролей логин

а в открывшемся окне ввести пароль (используя только латинские буквы). Чтобы добавить новые логины и пароли в уже имеющийся файл, эту программу следует запускать без параметра -с.

По традиции файл с паролями посетителей принято называть .htpasswd. Обычно Apache настраивается так, что файлы с именами .htaccess и .htpasswd невозможно просмотреть через Web — при такой попытке будет выдаваться лишь сообщение о запрещении доступа. Однако выполнение такой настройки (для этого надо указать не-сколько параметров в httpd.conf — конфигурационном файле Apache) — целиком на совести администраторов web-сервера.

Обратите внимание, что путь к файлу паролей следует указывать абсолютный — то есть от корневого каталога сервера с указанием всего дерева каталогов. На серверах хостинга он обычно имеет вид /pub/home/имя аккаунта/. /имя файла паролей, а на вашем локальном компьютере зависит от местоположения web-сервера и его настроек, например, может выглядеть и как f:/www/exper/cov/.htpasswd.

AuthUserFile /pub/home/exper/cov/.htpasswd require valid-user

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

Итак, пожелав "запаролить" доступ к ресурсам какой-либо папки, создайте файл с именем .htaccess с вышеуказанными параметрами.

Сделать это командой "Проводника" или "Нортона" вам не удастся, так как эти программы не допускают создание файлов без имени (а .htaccess они воспринимают именно как расширение без имени!), поэтому наберите соответствующий текст в какой-нибудь программе, позволяющей это совершить (например, ViewText Геор-гия Гуляева, http://www.altailand.ru).

Создав файл .htaccess, загрузите программу для создания файла па-ролей и поработайте с нею. После этого загрузите оба файла на свой сайт: .htaccess — в закрываемую папку, а файл с паролями — в соответ-ствии с прописанным в .htaccess путем к нему (рис.8.2).

Вот и все! Теперь при попытке запроса любого ресурса из защи-щенной папки (в том числе и картинок, включенных в другие страни-цы тэгом ) посетителю будет выдан стандартный запрос ло-гина и пароля (рис.8.1). Если логин и пароль совпадают с хранящими-ся в файле паролей (по умолчанию есть три попытки ввода), то доступ разрешается, если нет — средствами web-сервера выводится соответст-вующее сообщение.

Рис.8.1. Запрос на вход в папку.

Рис.8.2. Пароль на папку средствами web-сервера?

Достаточно двух файлов — .htaccess и .htpasswd…

Доступ открывается "для определенного окна браузера и всех его дочерних окон". Иными словами, если посетитель однажды ввел пра-вильные логин и пароль, то он, работая в одном и том же окне браузе-ра, может не только свободно путешествовать по всем ресурсам в за-пароленной папке, но и, выйдя из нее, свободно вновь в нее войти. То же самое верно и для всех окон браузера, открытых из исходного с помощью команды "открыть в новом окне". А вот если он откроет но-вое окно браузера и зайдет уже в нем в эту папку, то запрос на ввод логина и пароля появится вновь (разумеется, если страница не была взята из кэша браузера — в последнем случае достаточно ее обновить).

Использовать данный способ удается не всегда, — администрация сервера иной раз не позволяет это делать посетителям, да и програм-ма для создания файла паролей не всегда под рукой. Однако средства PHP позволяют обойтись без применения файлов .htaccess.

Авторизация с помощью заголовка

В PHP есть команда Header — она позволяет отправить браузеру по-сетителя, запросившему страницу с содержащим эту команду сцена-рием, определенную служебную информацию — так называемый "за-головок". Существует довольно много вариантов заголовков (напри-мер, заголовок "Location: http://адрес" приведет к перенаправлению на указанный URL; то же самое, что и при использовании мета-тэга http-equiv с параметром "Refresh"), однако для авторизации нам потребу-ется заголовок "WWW-Authenticate".

Заголовок — это данные, передаваемые браузеру до передачи самой web-страницы, сообщающие ему некоторые параметры передаваемого файла или опре-деленные команды. Список всех возможных заголовков, которые обязаны поддер-живать современные браузеры, можно найти в спецификациях протокола HTTP — они есть, например, на сайте http://www.w3.org. PHP-команда Header (параметр) выполняет всего одно действие — она просто передает то, что указано в ее парамет-ре, в браузер, запросивший страницу, на которой она находится, в качестве заголов-ка.

Следует помнить, что заголовок должен передаваться в браузер до любого дру-гого вывода в него, за исключением установки cookie.

В том случае, если браузер получает заголовок "WWW-Authenticate", то он выдает посетителю стандартное окно для ввода логина и пароля, которое вы наверняка много раз видели (как на рис.8.1). Как только посетитель нажимает кнопку Ok этого окна, браузер вновь заходит на ту страницу, с которой этот заголовок был ему послан, но на этот раз уже передает сценарию на этой странице две переменные — то, что было введено в поля ввода логина и пароля. Web-сервер дает этим переменным имена $PHP_AUTH_USER и $PHP_AUTH_PW, и их становится можно использовать в остальных сценариях на странице как любые другие переменные — использовать в выражениях, сравнивать с каким-либо эталоном, присваивать им какие-либо другие значения, наконец.

Если посетитель нажимает кнопку Cancel в диалоговом окне запро-са логина и пароля, то выполнение кода страницы просто продолжа-ется со следующей строчки за командой Header. Никакие перемен-ные странице не передаются.

Однако переменные $PHP_AUTH_USER и $PHP_AUTH_PW — не простые. Если они один раз были определены, то впоследствии они передаются всем web-страницам, которые загружаются в то же самое окно браузера, где произошла авторизация! Иными словами, если по каким-то причинам требуется проверять логин и пароль посетителя на каждой из страниц сайта (скажем, выводить разную информацию ав-торизованным и неавторизованным посетителям), то каждый раз за-прашивать эти данные не нужно — достаточно использовать значения переменных $PHP_AUTH_USER и $PHP_AUTH_PW. Значения дан-ных переменных теряются в случае закрытия окна браузера, в кото-ром изначально произошла авторизация (а в другие окна они и не пе-редаются). При выходе за пределы виртуального сервера, на котором произошла авторизация (обычно его границы совпадают с границами аккаунта), данные переменные перестают передаваться страницам, однако при повторном входе на исходный адрес вновь становятся доступными (это обеспечение безопасности — за пределами вашего виртуального сервера логины и пароли ваших посетителей никто уз-нать из их браузеров не сможет).

Кстати, при использовании предыдущего способа — средствами Apache — в переменные $PHP_AUTH_USER и $PHP_AUTH_PW тоже помещаются значения логина и пароля, введенные пользователем. В принципе вы можете найти им какое-нибудь применение.

К примеру, вспомним содержание седьмой главы, в которой рас-сматривалась программа для самостоятельной загрузки посетителями файлов на сайт. Помните, в чем была проблема — проверка пароля и сама загрузка файлов совершались сценарием на одной и той же стра-нице, и в случае ошибки при вводе пароля посетитель все равно был вынужден ждать окончания загрузки файла на сайт, чтобы тот был сразу же оттуда удален? Так вот — используя данный способ авториза-ции (и предыдущий — средствами Apache — тоже), можно разделить авторизацию и закачку файлов, предоставив посетителю возможность вначале ввести логин с паролем, а только потом, если они правиль-ные, выдать ему форму для закачки файла. Если добавить на страницу обработки закачанного файла краткую программу для проверки пере-менных $PHP_AUTH_USER и $PHP_AUTH_PW, то можно не бояться захода на страницу загрузки неавторизованных посетителей (скажем, по закладке или путем прямого набора ее адреса в браузере) — таковые будут отсеяны, а запросы легальных обработаны.

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

Итак, начало сценария. Обратите внимание, что для того, чтобы он сработал, до команды Header в выдаваемый документ не должно ничего выводиться: ни результат выполнения команд PHP, ни про-стое содержимое страницы, — так уж воспринимают web-страницы браузеры. В частности, данный сценарий должен располагаться в са-мом начале страницы, и символы

Поскольку после выдачи окна авторизации браузер вновь вызывает web-страницу, передавая ей авторизационные данные, то можно про-верить их еще до отправки браузеру заголовка WWW-Authenticate. В самом деле — если окно авторизации не выводилось вообще, то пере-менные $PHP_AUTH_USER $PHP_AUTH_PW будут пустыми (вер-нее, вообще не определены), а если выводилось — то в них окажется информация, введенная посетителем (то есть логин и пароль).

Наиболее простым вариантом будет указание логина и пароля в тексте самой программы авторизации — ведь все равно код на PHP, размещающийся на странице, посетители увидеть не смогут (Вернее, смогут лишь в том случае, если данный код располагается в файле не с тем расширением, которое указано в настройках web-сервера как признак страниц с программами на PHP). В этом случае команда проверки содержимого переменных $PHP_AUTH_USER и $PHP_AUTH_PW на соответствие указанным будет выглядеть как

if (($PHP_AUTH_USER!="login")||($PHP_AUTH_PW!= "parol")) 

Дальше идет тот код, который выполняется в случае несоответст-вия содержимого переменных указанным в команде логину и паролю. В случае самой первой загрузки страницы он, естественно, тоже вы-полнится — переменные $PHP_AUTH_USER и $PHP_AUTH_PW в та-ком случае еще не будут определены.

Итак — выдаем окно авторизации, для чего посылаем браузеру со-ответствующий заголовок:

Header("WWW-Authenticate: Basic realm=\"Защищенная зона"\"");

Браузер, получив такое, выдаст посетителю окно (такое же, как на рис.8.1) с запросом логина с паролем. После нажатия кнопки Ok стра-ница будет загружена вновь и в том случае, если логин и пароль соот-ветствовали указанным в ее тексте, будет выводиться остальной ее текст — тот, что последует за командой if, за ее закрывающей фигур-ной скобкой. Ну, а если логин и пароль будут введены неправильно, то окно авторизации выскочит вновь — и у посетителя появится еще один шанс правильно авторизоваться. И так до тех пор, пока не будут введены правильные логин и пароль.

Однако в выдаваемом окне есть еще кнопка "Отмена"! И в том случае, если посетитель нажмет ее, то код просто начнет выполняться дальше, со следующей после Header команды. Следовательно, в этот код и нужно вставить те команды, которые сообщают посетителю, так и не сумевшему ввести правильные логин с паролем, что он не может войти в защищенную зону. (Не забудьте, что все эти команды должны находиться в пределах блока оператора if — ведь нам надо, чтобы они выполнились только в случае нажатия кнопки "Отмена"!).

Выдадим браузеру заголовок, сообщающий об отказе в авториза-ции (требуется некоторым браузерам, а заодно и обнуляет перемен-ные $PHP_AUTH_USER и $PHP_AUTH_PW):

Header("HTTP/1.0 401 Unauthorized");

…а затем — укажем тот текст, который должен быть выдан посети-телю в случае отказа в авторизации — то есть нажатия им кнопки "От-мена" в диалоговом окне:

echo ("

Доступ закрыт!

");

(При желании вы можете сделать целую web-страницу, на которой подробно рассказать, например, как можно достать правильные логин с паролем, и вставлять ее текст сюда в случае отказа в авторизации с помощью команды include:

include ("noauth.php");

Например, так стоит сделать, если код этой страницы весьма большой или одна такая страница будет использоваться для несколь-ких мест авторизации.)

И, наконец, завершим работу с текущей страницей — нам ведь не нужно выполнять тот код, что дальше; он ведь должен быть доступен только авторизованным посетителям. Для выхода используем комаду exit:

exit; >

Она полностью прекращает как вывод web-страницы посетителю, так и выполнение какого-либо кода.

Вот, собственно, и все:

Для наглядности — все строчки кода вместе:

…команды вывода текста страницы, выдающейся посетителю в случае нажатия им кнопки "Отмена"…

exit; > ?>

Указание логина и пароля в самом тексте PHP-сценария — простой, но не очень удобный способ их хранения. В самом деле — если вы планируете предоставить доступ нескольким посетителям, то вам придется давать им одну и ту же пару логина и пароля. Это чревато тем, что при необходимости отказать кому-нибудь из них в доступе придется менять пароль, о чем придется сообщать всем остальным.

Ниже приводится небольшой код, реализующий проверку содер-жимого авторизационных переменных на совпадение с какой-нибудь парой "логин-пароль" из специального файла паролей. Допустим, файл, содержащий логины и пароли, располагается в папке passw и называется passwr, а формат его прост — запись типа "логин пароль" (через пробел) на каждой строчке (см.рис.8.3).

Рис.8.3. Простейший файл паролей.

Для того, чтобы какой-либо файл, с которым работает сценарий (в частности, файл с паролями в разбираемом примере), нельзя было загрузить через web-интерфейс, просто набрав его имя (и тем самым получив на экран все его содержи-мое), можно предпринять следующее:

1. Сделать это имя как можно более длинным и заковыристым (все равно оно фигурирует только в программном коде, то есть из Сети его узнать будет никак нельзя).

2. Поместить в папку с файлом (в нашем примере — в папку passw) файл с име-нем .htaccess со следующим кодом:

Order Allow,Deny Deny from All

Этот код запрещает что бы то ни было загружать из этой папки из Интернета, в то же время оставляя возможность работать с ее содержимым из сценариев. Поэто-му при использовании такого способа в папку с "защищенным" файлом не следует помещать web-страницы, которые должны быть доступны посетителям напрямую, через браузер.

3. Установить атрибуты файла так, чтобы они запрещали работу с ним группе "Public", например, поставив их в 770 (в CuteFTP это делается пунктом CHMOD из контекстного меню файла).

4. Указать в файле настроек web-сервера Apache (именующемся httpd.conf) в разделе описания соответствующего виртуального сервера параметр Location:

 deny from all 

но сделать это вы сможете, только если являетесь администратором web-сервера.

Рис.8.4. Средства закрытия папки от чтения ее файлов че-рез Сеть.

Итак, начнем сценарий. Для удобства используем в нем в качестве пометки о прохождении авторизации отдельную переменную — назо-вем ее $rez. Запросив в начале сценария у посетителя логин с паро-лем и проверив их, присвоим переменной $rez значение 1, если они правильные. А впоследствии при необходимости вывести на web-страницу что-то, что должно быть видно лишь авторизованным поль-зователям, будем проверять значение этой переменной: если оно рав-но 1, то авторизация прошла успешно, если нет — то посетитель не знает правильных логина и пароля. Так проще, чем каждый раз про-водить просмотр файла паролей.

Для начала присвоим переменной $rez значение 0 — ведь иначе любой, кто, зайдя на эту web-страницу, укажет в адресной строке браузера после имени страницы параметр rez=1 (это, например, мо-жет выглядеть как "http://www.******.ru/auth.php? rez=1") , тем самым "обманет" сценарий и заставит его считать, что авторизация уже выполнена правильно. Ведь, как вы помните, пара-метры, указываемые в адресной строке браузера после имени web-страницы со сценарием на PHP, становятся переменными в этом са-мом сценарии (Если в файле настроек PHP php.ini включена в On опция register_globals). Бесспорно, для такого обмана потребуется знать имя и нужное значение этой самой переменной-"пометки", но мало ли, вдруг это откуда-либо будет известно злоумышленнику…

Командой file считаем файл построчно в массив…

Команда file помещает в массив указанный в ее параметре файл, помещая ка-ждую строку файла в отдельный элемент массива.

…и начнем сравнивать пару "логин-пароль" каждой строчки файла (т.е. каждый элемент массива) с той парой, что мы получили от поль-зователя. Массив даже нет нужды именовать — достаточно просто ука-зать команду file в цикле foreach (как упоминалось в предыду-щей главе, этот оператор считывает каждый элемент указанного в его параметрах массива в переменную с именем, указанным после ключе-вого слова as, и выполняет для каждого элемента массива код, ука-занный в фигурных скобках).

foreach (file("passw/passwr") as $k) 

Оператор foreach будет работать только в PHP 4.0 и выше. Если вы можете ис-пользовать лишь PHP3, то вместо этого оператора можно использовать цикл for, указав в его параметрах величину массива:

$b=file("passw/passwr"); for ($i = 1; $i < $sizeof($b); $i++) 

Для удобства можно записать значение очередного элемента массива в пере-менную:

$value=$k[$i];

Поскольку каждая строчка файла завершалась символом перевода строки (вернее, двумя символами — с ASCII-кодами 10 и 13), то его необходимо удалять перед сравнением (в введенных пользователем значениях символа перевода строки-то нет!) — это делает функция substr.

if (substr($k, 0, -2)=="$PHP_AUTH_USER $PHP_AUTH_PW") 

Примечание:

Команда substr предназначена для выделения из строки ее части. Строка (или переменная, ее содержащая) должна быть указана в первом параметре команды. Второй параметр — позиция, с которой начинается выделяемая часть (вернее, число символов, которые необходимо пропустить до начала выделения части строки), а третий — количество выделяемых символов.

Второй параметр может быть и отрицательным. В этом случае отсчет позиции начала выделяемой части будет идти не с начала, а с конца строки. Иными словами, в результате выполнения команды substr ("qwertyuiop", -3, 2) из строки "qwertyuiop" будет выделена строка io — она начинается за 3 символа от конца ис-ходной строки и продолжается 2 символа.

Третий параметр тоже может быть отрицательным. В этом случае будет выделе-на строка, начинающаяся с указанной во втором параметре позиции и оканчиваю-щаяся за столько символов до конца строки, сколько указано в третьем параметре. Иными словами, в результате выполнения команды substr ("qwertyuiop", 3, -2) из строки "qwertyuiop" будет выделена строка rtyui — она начинается после 3 символа исходной строки и заканчивается за 2 символа до ее окончания.

В том случае, если параметры установлены так, что выделить согласно им сим-волы из строки оказывается невозможно (например, второй параметр больше, чем число ее символов), то результатом работы команды substr будет пустая строка — "".

Если в файле с паролями была найдена пара "логин-пароль", сов-падающая с данными, введенными пользователем, то присвоим пере-менной $rez значение 1. Впоследствии ниже, когда нам надо будет проверить, совершилась ли авторизация, просто будем проверять зна-чение этой переменной — так проще, чем вновь проводить просмотр файла паролей.

$rez=1; > >

Собственно, и все — проверка завершена. Теперь в том случае, если переменная $rez не равна 1, следует выдать окно авторизации и полу-чить от посетителя логин и пароль, а если равна — то выводить стра-ницу дальше. Как помните, возможности установить значение этой переменной в 1 через указание ее в адресной строке мы воспрепятст-вовали, установив $rez в 0 в начале сценария.

if ($rez!=1) < Header("WWW-Authenticate: Basic realm=\"Защищенная зона"\""); Header("HTTP/1.0 401 Unauthorized");

…команды вывода текста страницы, выдающейся посетителю в случае нажатия им кнопки "Отмена"…

exit; > ?>

Как уже говорилось, переменные $PHP_AUTH_USER и $PHP_AUTH_PW передаются всем страницам, которые загружаются в то же самое окно браузера — то есть на которые посетитель перехо-дит. Поэтому их можно использовать для проверки его прав на вы-полнение того или иного действия без новых запросов. Скажем, если на какой-нибудь странице, на которую посетитель должен перейти лишь после авторизации, должна производиться загрузка файла, то перед загрузкой (в сценарии-обработчике загруженного файла, под-робнее — см.главу 7) следует вновь проверить соответствие передан-ных этой странице переменных $PHP_AUTH_USER и $PHP_AUTH_PW какой-нибудь паре логина и пароля в файле паро-лей:

Данный код просматривает файл с паролями (да, опять тот же файл…) и определяет, есть ли там такая же пара "логин-пароль", как и та, что записана в переданных странице переменных. Если есть — файл загружается, если нет (т.е. посетитель зашел на страницу с формой для загрузки файла, скажем, по сделанной в "Избранном" закладке или введя ее URL в адресную строку браузера, миновав страницу ав-торизации) — то загрузки не происходит.

Иными словами — один раз введенные посетителем правильные ло-гин с паролем записываются в переменные $PHP_AUTH_USER и $PHP_AUTH_PW до тех пор, пока посетитель не закроет окно браузе-ра (и все окна, открытые по ссылкам командой "Открыть в новом ок-не" из окна, где произошла авторизация). На тех страницах, куда по-сетитель может попасть после авторизации, значения этих перемен-ных можно проверять, сравнивая с каким-либо эталоном, например, записанными в скрытом файле логинами и паролями, и выдавать по-сетителю в зависимости от соответствия эталону его авторизацион-ных данных разную информацию. Это предотвратит возможность по-пасть в "закрытую зону" помимо окна авторизации, через набор адре-са в адресной строке или по закладке.

Например, для отправки на страницу авторизации всех, кто ее не прошел, можно воспользоваться кодом

 > if ($rez!=1) < Header ("Location: auth.php"); >?>

где auth.php — страница с кодом выдачи окна авторизации. Заголо-вок Location, переданный браузеру, вызывает его переход на указан-ную в нем страницу. Так как в данном коде используется команда Header, то она сработает без ошибок лишь в том случае, если до нее в браузер посетителя ничего не выдавалось (кроме разве что других за-головков и cookies).

Особенности описанного способа авторизации довольно очевидны. Например, данные авторизации сохраняются в переменных лишь в течение одного сеанса работы посетителя; достаточно ему закрыть окно браузера, чтобы необходимость ввода логина и пароля возникла снова. Для заполнения полей окна авторизации нельзя использовать имеющуюся во многих браузерах функцию автозаполнения форм (со-временные браузеры могут запоминать соответствие определенному URL лишь одной пары "логин-пароль" и подставлять именно ее в по-ля окна), да и в интерфейс страницы это окно вписать никак нельзя (оно ведь отображается браузером).

Однако есть еще один прием регламентации доступа к страницам сайта — с использованием файлов cookies. Им мы сейчас и займемся.

Авторизация с помощью cookies

Cookie — это файл в специальном формате, который присылается сервером браузеру посетителя сайта, расположенном на этом сервере (рис.8.5). Браузер, если он поддерживает cookie (и эта поддержка в нем не отключена), помещает его в особое место и впоследствии от-правляет назад на сервер при поступлении от него запроса. Иными словами, cookie позволяет серверу хранить свою информацию на компьютерах посетителей и считывать ее оттуда при необходимости. (Современные стандарты безопасности предусматривают, что каждый сервер (Вернее, узел с собственным доменным именем (любого уровня)) может получить назад только те cookie, которые были уста-новлены лично им, так что даже о том, какие сайты еще посещал по-сетитель, с помощью cookie узнать нельзя.)

Рис.8.5. Cookie изнутри.

Cookie

Cookie можно установить (т.е. прислать на компьютер посетителя) и средствами PHP. Для этого используется команда SetCookie, имеющая параметры: имя cookie, информация, записанная в cookie, время жизни cookie — указывается количе-ство секунд, после истечения которых с 1 января 1970 года cookie не должен считы-ваться с компьютера посетителя (так уж измеряется время в операционных систе-мах типа Unix — с начала "эпохи Unix" 01.01.1970), адреса сайта и каталога на нем, где cookie должен быть действителен, и указание на протокол передачи cookie (под-робнее смотрите в Описании PHP). Считать cookie можно простой командой echo ("имя cookie"). Можно сказать, что, как только cookie установлен, сценариям на всех страницах того сайта, на котором он был поставлен, становится доступна переменная с тем же именем, что и у cookie, и тем содержимым, которое было запи-сано в нем (если в файле настройки PHP установлен в on параметр register_globals).

Кроме того, значения cookie помещаются в массив $HTTP_COOKIE_VARS и доступны в его элементах, одноименных с именами cookie — $HTTP_COOKIE_VARS['имя cookie'] (если в файле настройки PHP установлен в on параметр track_vars), а в PHP версии 4.1 и выше — еще и в массив $_COOKIE.

Для удаления cookie достаточно записать в него пустое значение (это сделает команда SetCookie с единственным параметром — именем cookie).

Для установки времени жизни cookie можно сначала узнать текущее "время Unix" командой time(), а потом просто прибавить к нему то количество секунд, которое cookie должен просуществовать после его установки на компьютер посети-теля. Если время жизни для cookie не установлено, то он проживет до закрытия всех окон браузера посетителя.

Как и отправка заголовков командой Header, установка cookie должна пред-шествовать любому выводу в выдаваемый документ: как результатов выполне-ния команд PHP, так и простого содержимого страницы. Иначе возникнет ошибка.

Как cookie можно использовать для решения обсуждаемой в этой главе задачи — авторизации доступа? Да очень просто — запросив от посетителя логин и пароль, записать их в cookie, а потом на каждой странице "защищенной зоны" считывать их оттуда и проверять, име-ются ли такие данные в файле паролей. Ну и поступать в соответст-вии с результатом такого сравнения — например, отправлять те брау-зеры, которые не смогли представить cookie с правильными логином и паролем, прямиком на страницу авторизации, посылая им с помо-щью PHP-функции Header заголовок Location с соответствующим па-раметром, как было показано выше для предыдущего варианта авто-ризации.

Вот фрагменты сценария, в которых видна технология использова-ния cookies. На той странице, откуда должен осуществляться вход в "защищенную зону", следует поставить простую форму для ввода ло-гина и пароля (см.рис.8.6). Например, такую:

Логин:
Пароль:

Рис.8.6. Авторизация на основе cookies. Просто форма…

На той странице, имя которой указано в параметре ACTION заго-ловка формы, введенные данные проверяются, и в том случае, если такие логин и пароль имеются в файле паролей, браузеру посетителя отсылается cookie, куда эти логин с паролем записываются.

И вот — сама установка cookie под именем auth. Ему устанавливает-ся "время жизни" — 3600 секунд, то есть час.

SetCookie("auth","$login $pass",time()+3600); > > ?>

Дальше должен находиться сценарий, который в зависимости от исхода авторизации — т.е. значения переменной $rez — выводит раз-личную информацию. Например, можно отослать посетителя назад на исходную страницу командой Header ("Location…"), как в примере предыдущего раздела этой главы.

На всех остальных странице "защищенной зоны" должен находить-ся сценарий проверки содержимого переменной auth (то есть той, чье имя совпадает с именем поставленного cookie) — то есть точно такой же скрипт, как и на той, где cookie ставился, только строка проверки должна выглядеть как

if (substr($k, 0, -2)=="$auth"),

ну и, естественно, самой команды установки cookie быть не долж-но. Дальнейший текст страницы — на усмотрение web-мастера: если логин с паролем, полученные из cookie, есть в файле паролей, то, скажем, вывести форму для закачки файлов, если нет — то вежливо распрощаться…

Желательно также сделать страницу "выхода", включив в нее ко-манду установку cookie без параметров — SetCookie ("имя cookie").

В результате в том случае, если посетитель единожды прошел ав-торизацию, то он может спокойно посещать страницы "защищенной зоны" до тех пор, пока cookie "жив" на его компьютере. Он может за-крыть окно браузера и даже выключить компьютер, а потом, включив его, вновь зайти на тот же адрес, используя "Историю" браузера или "Закладки"- и он будет авторизован, если время жизни cookie не ис-текло. Зато те, кто "подглядит" этот адрес или украдет закладку, но не будет иметь соответствующего cookie, авторизованы не будут

В отличие от предыдущего способа, данный вариант не является абсолютно надежным в плане сохранности в тайне логина с паролем. Во-первых, cookie с этими данными сохраняется на компьютере посе-тителя, а значит, теоретически может быть с него похищен (тем, кто просто сядет за этот компьютер и скопирует нужный cookie из той папки, где они хранятся). Во-вторых, возможность захода на web-страницу "защищенной зоны" в течение некоторого времени без не-обходимости ввода логина и пароля может привести и к нежелатель-ным последствиям — если посетитель забудет зайти на страницу выхо-да, то любой, кто воспользуется его компьютером до истечения срока действия cookie, с точки зрения сервера будет вполне легальным пользователем и сможет устроить истинному владельцу логина нема-ло проблем.

Стоит сказать, что использовать имя cookie как переменную можно только в том случае, если в файле настройки PHP — php.ini — есть па-раметр register_globals. Там, где этого параметра нет (например, в PHP версии 4.2 и выше он по умолчанию неактивен), работать с cookies как с обычными переменными не получится. Информацию, помещен-ную в них, придется получать из массива с названием $HTTP_COOKIE_VARS (он создается автоматически при обнаруже-нии cookies от данного сайта), используя имя нужного cookie в каче-стве индекса:

В PHP версии 4.1 и выше вместо $HTTP_COOKIE_VARS можно использовать массив $_COOKIE.

Надеюсь, вы поняли, что все эти проверки логинов и паролей в cookies и передающихся между окнами переменных, о которых так подробно рассказывается в этом и предыдущем пунктах, предназна-чены для одной цели — чтобы тот, кто каким бы то ни было образом узнал бы адрес страницы из "защищенной зоны" и зашел бы на эту страницу путем набора ее адреса в адресной строке браузера (или с помощью ярлыка в "Избранном"), не мог бы увидеть на ней то же са-мое, что и добросовестно прошедшие авторизацию посетители. Чтобы не приходилось запрашивать от посетителей пароль и логин на каж-дой странице, где есть возможность совершить те действия, которые крайне нежелательно позволять делать всем подряд — как, например, загрузка файлов или просмотр личной почты — а дать посетителям возможность, единожды введя авторизационные данные, свободно перемещаться по "защищенной зоне". Именно это и является основ-ной задачей описанных технологий.

Авторизация с помощью сессий

Вы, наверное, уже заметили особенность обоих вышеописанных способов авторизации — проверка правильности логина и пароля осу-ществляется на каждой странице, где требуется авторизованный дос-туп. Если посетителей на сайте не очень много, то это вполне допус-тимо, однако при большом числе авторизованных посетителей на-грузка на web-сервер может оказаться немалой.

В связи с этим возникает вопрос: а нельзя ли как-нибудь избежать необходимости каждый раз осуществлять проверку логина и пароля посетителя? Чтобы, единожды авторизовав посетителя, впоследствии предоставлять ему доступ на страницы защищенной зоны без каких-либо проверок? Именно так, кстати, действует защита на основе средств web-сервера — файлов .htaccess, описанная в первом разделе главы. Но можно ли сделать то же самое средствами PHP? Да и вооб-ще использовать cookie для хранения паролей не очень желательно: его содержимое может узнать любой, кто воспользуется компьюте-ром, на котором этот cookie сохранен (многие браузеры хранят cookie в предназначенной для них папке, даже если "время жизни" cookie истекло и он больше не принимается сервером).

Напрашивается первое предложение: а почему бы, например, после успешной авторизации не отправить посетителю cookie с какой-либо пометкой (например, устанавливать в 1 значение переменной в этом cookie), а впоследствии проверять не наличие записанных в cookie ло-гина и пароля в файле паролей или базе данных, а присутствие в cookie этой самой пометки, одинаковой для всех, прошедших автори-зацию? Или даже сделать разные типы пометок и в зависимости от типа предоставлять посетителю разные возможности на сайте?

Сделать-то так можно, да вот устойчивость такой системы автори-зации к взлому будет не особо великой. Злоумышленнику будет дос-таточно узнать, что за пометку помещает сценарий авторизации в cookie, чтобы получить к защищенной зоне полный доступ — просто вручную создав такой cookie. (А если при проверке "пометки" ис-пользовался не элемент массива $HTTP_COOKIE_VARS, а одно-именная переменная, то и просто подставив ее значение в адресной строке при заходе на страницу с такой проверкой: например, page.php?auth=1.) Кроме того, просмотреть значение cookie на компьютере посетителя и узнать, какие его имя и значение являются "пометкой", тоже не так трудно.

Но самое главное — посетители нередко отключают использование cookie при своих путешествиях по Интернету. При отключенных cookie описанная выше система авторизации на их основе работать не будет.

Следует использовать весьма интересный механизм сессий, поя-вившийся в 4-й версии PHP.

Сессии

"Сессия" — несколько абстрактное понятие, означающее нечто вро-де "законченного периода работы с сайтом". Например, в сессию могут входить такие действия, как "приход на сайт — загрузка данных — уход с сайта". Иногда определения сессии разнятся в своей форму-лировке, но суть примерно такая.

Так вот — с помощью команд "поддержки сессий" PHP можно при заходе посетителя на сайт запоминать какие-либо переменные и по-том эти переменные считывать или изменять на других страницах этого сайта. При этом — обратите внимание — в браузер посетителя пе-редаются отнюдь не сами эти переменные, а некий пароль, по кото-рому сервер впоследствии этот браузер узнает и восстановит именно те значения переменных, которые были установлены для данного по-сетителя.

Иными словами — работа механизма сессий в PHP происходит так. Когда посетитель заходит на сайт и для него устанавливаются какие-либо переменные (сам ли он их вводит или, скажем, они берутся из базы данных), то команды начала и регистрации сессии сохраняют эти переменные в определенном месте на самом сервере (в специаль-ном файле в папке временных файлов сервера, рис.8.7, 10.8).

Рис.8.7. Файлы с данными сессий

в папке временных файлов сервера.

Имена файлов соответствуют идентификаторам сессий.

Рис.8.8. Содержимое одного из таких файлов.

В сессии сохранены переменные: legus, wq1, wq2, wq3.

Если у посетителя браузер принимает cookie, то ему высылается cookie (с определенным именем — по умолчанию "PHPSESSID"), со-держащий так называемый "идентификатор сессии" (рис.8.9), а если нет, то web-сервер автоматически помещает данный идентификатор в переменную PHPSESSID в каждую ссылку (рис.8.10) на выдаваемых посетителю страницах сайта (естественно, "внутреннюю" — то есть ве-дущую на другие страницы того же самого сайта, с тем же самым до-менным именем). Таким образом, идентификатор передается на сер-вер при каждом заходе посетителя на какую-либо из страниц сайта, будучи либо взятым из соответствующего cookie, установленного по-сетителю при открытии сессии, либо из адресной строки ссылки, куда этот идентификатор автоматически помещается web-сервером.

Рис.8.9. Содержимое сookie с идентификатором сессии.

Рис.8.10. Ссылка с идентификатором сессии.

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

Идентификатор сессии каждый раз создается новый, и алгоритм генерации довольно хороший — вероятность того, что для какой-либо последовательности символов на определенном сервере будет суще-ствовать набор сохраненных переменных, пренебрежимо мала. Еще меньше вероятность совпадения двух идентификаторов сессий, так что разные посетители сайта ну никак не смогут получить значения переменных друг друга.

Бесспорно, набор сохраненных переменных, относящихся к одной сессии, будет существовать на сервере не вечно. В параметрах файла конфигурации PHP — php.ini — указывается, какое время жизни уста-навливается для cookie с идентификатором сессии (по умолчанию 0 — то есть до закрытия окна браузера и всех открытых из него окон), а также через какое время данные сессий из папки временных файлов удаляются физически (рис.8.11). Кроме того, существует специальная команда "разрушения сессии", которая при своем выполнении унич-тожает сохраненные в папке временных файлов данные сессии и тем самым делает недействительным идентификатор сессии. Параметры устанавливаемых cookie, в частности, их "время жизни" также можно задать специальной командой в сценарии на PHP, однако время хра-нения данных сессии в папке временных файлов определяется пара-метром в php.ini, так что при использовании виртуального хостинга вам не всегда удастся настроить работу с сессиями полностью так, как вам бы хотелось.

Рис.8.11. Файл php.ini, раздел настроек параметров сессий.

Чтобы использовать в сценарии на странице возможности работы с сессиями, необходимо включить в него команду session_start() (Так как при работе с сессиями используются cookie, то данная команда должна находиться в начале страницы, перед какими-либо выводимыми в браузер данными), — как при первоначальной установке перемен-ных, так и при последующей работе с ними (Если в файле php.ini установлен в 1 параметр session.auto_start, то это делать не обязательно). Чтобы указать, какие переменные следует сохранять в качестве данных сессии, следует ис-пользовать команду session_register("имя первой пере-менной", "имя второй переменной",… и т.д.), а чтобы закрыть сессию — команду session_destroy(). При закрытии сес-сии переменные, переданные сценарию с ее помощью, не обнуляются (последнее делает команда session_unset();), так что их можно использовать и в остальной части сценария.

Переменные сессии доступны на сценариях сайта по своим изна-чальным именам — скажем, если командой session_register пе-ременная $a была зарегистрирована в качестве сессионной, то ее зна-чение будет доступно под тем же самым именем — $a — на всех страни-цах сайта, где используются сессии (т.е. в их начале размещена ко-манда session_start()).

Однако в целях большей безопасности лучше работать в сценарии с переменными сессии через автоматически создаваемые массивы $HTTP_SESSION_VARS и (в PHP версий 4.1 и старше) — $_SESSION, используя одноименные этим переменным элементы этих массивов. Дело в том, что тогда сценарий будет огражден от возможных попы-ток злоумышленников передать ему значения этих переменных через указание их в адресной строке в том случае, если сессия не была от-крыта (в указанные массивы попадают те и только те данные, что бы-ли получены с сессией). Такая передача может привести, скажем, к тому, что переменная — пометка об успешном прохождении авториза-ции будет получена сценарием не из данных сессии (в которых она может появиться только после успешного ввода посетителем пра-вильных логина и пароля), а от злоумышленника.

Сценарий авторизации

Алгоритм сценария прост. После определения допустимости по-лученных от посетителя каким бы то ни было образом (вводом в фор-му или в диалоговое окно авторизации) логина и пароля открывается сессия и в ней регистрируется переменная — указатель на успешную авторизацию, которой присваивается определенное значение. На каж-дой странице "защищенной зоны" проверяется значение полученной с данными сессии этой переменной (а, как вы помните, берется оно не из отправляемых браузером посетителя данных, а из созданного во временной директории сервера файла с данными сессии — браузер по-сетителя сообщает лишь идентификатор этого файла), и если оно сов-падает с обозначающим успешную авторизацию, то посетитель до-пускается к работе со страницей, если же нет — то доступ к странице не разрешается. На странице "выхода" из защищенной зоны распола-гается команда session_destroy();, после выполнения которой идентификатор сессии "забывается" сервером и передача сценарию переменной — указателя на успешную авторизацию происходить пере-стает — до нового прохождения авторизации.

Начало сценария на странице проверки логина с паролем может быть таким:

> if ($rez!=1) 

или таким (если логин и пароль передаются из формы в перемен-ных $login и $pass):

> if ($rez!=1)

Оба варианта были подробно рассмотрены в двух предыдущих разделах этой главы. В результате их выполнения нижеследующий текст сценария будет выполняться только в том случае, если введен-ные посетителем логин или пароль есть в файле логинов и паролей (имеющем в данном случае имя "passwr").

Продолжение же сценария довольно простое. Создаем сессию…

session_start();
session_register("auth");

…и устанавливаем ей определенное значение — дабы потом его и проверять.

$auth=1;

Собственно, и все.

Дальше следует текст страницы, которую посетитель должен уви-деть сразу же после успешной авторизации.

Так как идентификатор сессии обычно сохраняется в cookie, то вышеприведенный код должен стоять в самом начале страницы — что-бы сервер имел возможность работать с cookies: отправить cookie с идентификатором сессии браузеру посетителя. (Если браузер посети-теля не принимает cookie, то идентификатор сессии будет автомати-чески присоединяться ко всем найденным на данной странице ссыл-кам на другие ресурсы сайта.)

На каждой странице "защищенной зоны", в самом ее начале нужно поставить код

…и все, что после этого кода, будет выполнено и/или выдано посе-тителю только в том случае, если он успешно прошел авторизацию на первой странице. При заходе на страницу "защищенной зоны" брау-зер посетителя перешлет серверу cookie с идентификатором сессии, а сервер возьмет из своего временного хранилища значение всех пере-менных сессии и передаст их сценарию.

Обратите внимание на необходимость присвоения переменной-"пометки о санкционированности доступа" нулевого значения в нача-ле сценария — о причине этого было сказано выше.

Страница выхода из "защищенной зоны" должна содержать код (Если в файле php.ini установлен в 1 параметр session.auto_start, то ука-зывать команду session_start() на каждой странице, где используются пере-менные сессии или производятся действия с самой сессией, не обязательно)

После его выполнения для посещения страниц "защищенной зоны" вновь потребуется авторизация.

Если посетитель не воспользовался страницей выхода из защищен-ной зоны, то время, в течение которого из его браузера можно по-пасть на другие ее страницы, определяется настройками в файле php.ini. По умолчанию cookie с идентификатором сессии, устанавли-ваемый посетителю, существует до закрытия всех окон браузера, а сами данные сессии хранятся несколько часов. Существует команда session_set_cookie_params(), с помощью которой можно ус-тановить другое "время жизни" cookie, однако для изменения настро-ек в файле php.ini необходимо иметь права администратора для web-сервера.

Посредством сессий можно передавать между страницами сайта и другие данные. Например, при создании сценария Интернет-магазина, витрина которого занимает больше чем одну страницу, данные о зака-зываемых посетителем товарах имеет смысл передавать по страницам сайта в переменных сессии для последующего их оформления на спе-циальной странице как заказа, как, собственно, и делается на боль-шинстве подобных ресурсов Сети.

Так что, как видите, никаких особых секретов в технологии огра-ничения доступа нет. Авторизация пользователей на многих службах хостинга, web-интерфейсов почтовых систем, Интернет-форумах обычно строятся на тех же принципах, что и приведенные выше сце-нарии.

Реализовав данные приемы на своем сайте, вы можете, например, вполне спокойно приглашать к себе на работу ведущих отдельных разделов вашего сайта. Все компоненты для их удобной и безопасной работы у вас уже есть: и "папкопотрошилка", и "закачиватель фай-лов", теперь вот еще и "защищенная зона"… Разве что стоит добавить еще и нечто вроде "файлового менеджера", чтобы посетители могли и удалять, и переименовывать загруженные ими файлы. Но об этом — еще через пару глав.

Пример сценария

Вот пример сценария, в котором используется авторизация на основе заголовка WWW-Authenticate. Он состоит из двух страниц — на первой логин с паролем прове-ряются и в том случае, если они есть в файле паролей, то посетителю выводится форма для загрузки файла. На второй странице осуществляется загрузка файла.

> if ($rez!=1) < Header("WWW-Authenticate: Basic realm=\"Защищенная зона"\""); Header("HTTP/1.0 401 Unauthorized"); echo ("

Доступ закрыт!

"); exit; > ?> Закачать файл:

Файл 2.

 > if ($rez!=1) Доступ закрыт!

");exit;> if ($zak=="none") elseif (copy($zak, "папка для файлов/$zak_name")) else < echo("Не удалось скопировать $zak_name");>?>

Авторизация на сайте

Данный пример не претендует на звание идеального метода защиты, но все же обойти его будет достаточно трудно. Представим следующее: у вас есть закрытый сайт "для своих" и вы не хотите чтобы туда заходили всякие нехорошие личности. В этом нам помогут сессии. Пароли и логины будем хранить в таблице mysql.

На первой странице index.php делаем форму для ввода данных:














Имя:
Пароль:




Думаю здесь пояснять ничего не нужно. Идем дальше: Сначала краткое пояснение. Мы создаем функцию проверки пользователя check(). У нас есть база данных my_site, содержащая поля id, name и pass, где name и pass - логин и пароль пользователя соответственно. Функция пропускает только тех, кто указал верный логин и пароль в форме ($name, $pass) на входе, потом эти переменные сохраняются в сессию, следовательно, пока сессия жива пользователь может заходить на ваш сайт без авторизации. Даже указав другой верный логин и пароль, он будет авторизирован под указанным ранее логином.

Предполагается, что соединение с базой mysql уже произведено и база данных выбрана.

 function check() 
if (empty($pass)||empty($name))
error("Не указан логин или пароль");
$sql = "select * from my_site where login='".$name."'";
if ($show = mysql_query($sql))
$a = mysql_fetch_array($show);
if ($a['pass']!=$pass) error("Не верное сочетание логин - пароль");
>
else session_register("name","pass");
>
>
else error("Ошибка запроса к базе данных");
>
>
?>

Начнем пояснения с первой строки.

if (empty($pass)||empty($name))
error("Не указан логин или пароль");
 function error($er) 
echo $er;
exit(0);
>
?>
$sql="select pass from mysite where login='".$name."'";
if ($show=mysql_query($sql))
$a=mysql_fetch_array($show);
f ($a['pass']!=$pass) 
error("Не верное сочетание логин - пароль");
else 
session_register("name","pass");
> 
else
error("Ошибка запроса к базе данных");
>
?>

Если есть ошибка в запросе к базе mysql, то мы опять же выводим ошибку пользователю.

Итак, вначале каждой страницы, к которой нужно запретить доступ посторонним пишем:

 session_start(); 
/* эта функция открывающая или продолжающая работу с сессиями. Она должна быть задана в самом начале страницы до отправки заголовка страницы. */
check(); //наша функция проверки.
?>

Теперь проверим логику скрипта. Если человек не заполняет одно из полей и нажимает кнопку "вход", то перейдя на страницу index2.php он получит надпись "Ошибка: Не указан логин или пароль".

Если он указывает неверный логин или пароль, то ему выпадает "Ошибка: Не верное сочетание логин - пароль".

Если же он все указывает верно, то попадет на страницу index2.php где вы храните свои тайны. За счет того, что логин и пароль записываются в сессию, юзер может бродить по вашему сверх тайному сайту авторизировавшись только один раз.

Нельзя заходить на сайт под разными именами.
Если человек раз зашел на сайт, то с его компьютера можно посещать этот сайт еще в течении некоторого времени (пока жива сессия), что не очень хорошо, если ты работаешь из Интернет салона.

Автор: неизвестен
28.12.2008, 09:47

если сессию закрыть то можно будет потом зайти под другим логином и паролем?

03.01.2009, 13:56

Да, можно.
Ну если вы хотите 100% безопасности, то создайте файл .htaccess, и напишите в нем следующее:

AuthType Basic 
AuthName "auth"
AuthUserFile /www/site/.htpasswd
require valid-user

Потом создайте файл .htpasswd, и сгененируйте логин и пароль на http://www.htaccesstools.com/htpasswd-generator/

03.01.2009, 23:40
Сообщение от vvsh

AuthType Basic 
AuthName "auth"
AuthUserFile /www/site/.htpasswd
require valid-user

Потом создайте файл .htpasswd, и сгененируйте логин и пароль на http://www.htaccesstools.com/htpasswd-generator/

если это 100% защита, то почему я в и-нете не встречал всплывающие окошко от браузера с запросом на ввод логина и пароля? Я только видел использование форм на ввод логина и пароля.

04.01.2009, 17:39

Потому-что это неудобно. Например http://vvsh.ru/admin/

04.01.2009, 18:52
Сообщение от mawa

если это 100% защита, то почему я в и-нете не встречал всплывающие окошко от браузера с запросом на ввод логина и пароля? Я только видел использование форм на ввод логина и пароля.

это авторизация средствами самого сервера, и поэтому точно надежнее, ее минус - удобство, а второй минус это работа с добавлением изменением новых пользователей и паролей
т.к. для этого надо использовать инструменты сервера
ну и еще один минус, это то что кроме имени и пароля и папки больше нельзя указать уровень доступа

08.02.2009, 16:41
auth_admin.php

 $login = "admin";//Логин 
$pass = "";//md5 кеш Пароля
# Проверка вода логина и пароля
if(isset($_POST['login']))
if(isset($_POST['pass'])) // Если ввели пароль, кодируем md5 для дальнейшего сравнения
//==================================================================
// Остальная часть кода будет проверять схожесть логина и запись в Cookie
//==================================================================
if($_GET['auth']=='exit') < //Если пользователь выходит из панели
// ADMIn EXIT
setcookie("user","");
setcookie("pass","");
header("Location: admin.php");
exit();
>else if($_GET['auth']=='yes') if($vlogin==$login) if($vpass==$pass) setcookie("user","$login",time()+ "9100");
setcookie("pass","$pass",time()+ "9100");
$_SESSION['admin'] = true;
>
>
header("Location: admin.php");
exit();
>else if($_COOKIE['user']=="$login" && $_COOKIE['pass']=="$pass") setcookie("user","$login",time()+ "9100");
setcookie("pass","$pass",time()+ "9100");
$_SESSION['admin'] = true;
>
>
?>
 
include 'engine/auth_admin.php';
?>

Вы успешно авторизовались!!
else< ?>
Вход в админпанель.

LOGIN:

PASSWORD:


?>

Даже если ты узнаешь md5 кеш Пароля то войти все равно не сможешь :1124:
Кстати зачем копировать скрипты с других сайтов, а самому слабо написать?

15.04.2009, 17:59

#5 скажите пожалуйста, вот я не понимаю, как сессия будет читаться в начале других страниц если нё там указать просто как фунцию
session_start();
/* эта функция открывающая или продолжающая работу с сессиями. Она должна быть задана в самом начале страницы до отправки заголовка страницы. */
check(); //наша функция проверки.
?>

Другое дело если инклюдом, или типа в хэше данные храняться?:)

21.06.2009, 20:10
locky-yotun

Добрый день!
Тема еще жива? 😉
Ситуация такая:
Пытаюсь реализовать авторизацию на своем сайте, используя код, предложенный Webmaster'ом в посте #4. С md5-хешем и экранированием спец-символов у меня этот код работать не захотел (пока?), так что от использования md5 и mysql_escape_string я временно отказался. В итоге login.php выглядит вот так:

 
session_start();
header("Content-Type: text/html; charset=cp1251");

function show_form($message)
?>



Имя:



Пароль:



die();
>

//Проверка нажатия кнопки submit
if(!isset($_POST['subm'])) show_form('');
//Проверка на введенные данные
if(!isset($_POST['user']) OR !isset($_POST['pass']) OR empty($_POST['user']) OR empty($_POST['pass']))
show_form("Не правильная пара логин-пароль.");
// подключение к БД - соответственно прописываем свои данные доступа к базе данных
$connection = mysql_connect("localhost","root","") ;
mysql_select_db('mysite') ;
// НЕ смог достучаться до БД
if (mysql_error()) die();

$user = $_POST['user'];
$pass = $_POST['pass'];

// Проверяем есть ли пользователь с таким логином и паролем
$result = mysql_query("SELECT `id` FROM `checker` WHERE `name`='".$user."' AND `pass`='".$pass."'");

// если есть - впускаем
if(mysql_num_rows($result)==1)
$_SESSION['admin']=$adm;

// Если нет - пишем так.
else
show_form("Incorrect login-password.");

// Далее сообщение которое увидит вошедший пользователь
?>



Здравствуйте !

В итоге после ввода верной пары логин-пароль происходит редирект на news.html (это форма добавления новостей на сайт с внесением их в БД, должна быть доступна только администратору). НО! Если просто вбить в адресной строке %sitename%/news.html, то опять же попадаем на эту страницу, хотя логин и пароль не вводились.
Вопрос: что не так (если не так) в коде, и какой код надо добавить на news.html для того, чтобы зайти на них можно было только после аутентификации?
PS: Извиняюсь за возможную несвязность, надеюсь все понятно))

21.06.2009, 20:26
1) что такое $adm - эта переменная нигде не инициализируется, может лучше написать

// если есть - впускаем 
if(mysql_num_rows($result)==1)
$_SESSION['admin']=$user;
 session_start(); 
if( !isset($_SESSION['admin']) ) die('Access dinied!');
?>
unset($_SESSION['admin'])

21.06.2009, 20:28

на всех страницах которые подлежат авторизации
вы должны добавить код проверяющий
есть ли в переменной
$_SESSION['admin'] какое либо значение
для этого в самом начале файло надо написать

 session_start(); 
if (!isset($_SESSION['admin']) || $_SESSION['admin']) exit();
?>

21.06.2009, 23:03
locky-yotun

to Apay, Webmaster
Спасибо, разобрался, все работает! 🙂

upd:
Только с разлогиниванием непонятно. Пишу:

 









if(@$submit_edited) unset($_SESSION['admin']);
echo "Log out!";
>
?>

И никакого эффекта. Условие в if задано неверно? Или какая-то другая ошибка?

22.06.2009, 06:20

 



if(isset($_POST['submit_edited']) unset($_SESSION['admin']);
echo "Log out!";
>
?>

22.06.2009, 10:08
locky-yotun

Apay
Не помогло 🙁
В твоем коде я добавил ")" в if, иначе был sintaxys error. Я поставил проверку нажатия кнопки следующим образом:

 






if (isset($_POST['exit'])) //unset($_SESSION['admin']);
echo (""); >
?>
 
if (!isset($_POST['exit'])) //unset($_SESSION['admin']);
echo (""); >
?>

, то редирект осуществляется моментально при загрузке страницы.
В чем может быть причина?

22.06.2009, 10:30
locky-yotun
На всякий случай привожу весь код страницы:

 
session_start();
if( !isset($_SESSION['admin']) ) die('Access dinied!');
?>









Добавление новостей








Добавление новостей



















Добавить новость
Аннотация :
Сообщение :
















































if (isset($_POST['exit'])) //unset($_SESSION['admin']);
echo (""); >
?>



22.06.2009, 10:49

один вопрс, я писал

где форма.

22.06.2009, 12:57
locky-yotun

Спаасибо, запарился - не заметил) Все работает! 🙂

09.09.2009, 05:40
подскажите

Доброго времени суток!
Помогите пожалуста. Распишите все по порядку от начала и до конца
как можно выложить сайт на хост так чтобы на нем регестрация была ?
я и базы в denwere делал и скрипты качал только не понял как мой сайт с этими базами связать :1128::1128:

09.09.2009, 07:24
Сообщение от sis

Доброго времени суток! Помогите пожалуста. Распишите все по порядку от начала и до конца как можно выложить сайт на хост так чтобы на нем регестрация была ?

шаг 1) делаете все у себя на компе (денвер есть)
шаг 2) копируете все скрипты на хостинг
шаг 3) подправляете значения $server, $username, $password, $database_name в соответствии с тем что вам дали хостеры

Сообщение от sis
не понял как мой сайт с этими базами связать

mysql_connect( $server, $username, $password ); 
mysql_select_db ( $database_name );

09.09.2009, 11:06

Apay,
спасибо
получилось:0051:

13.10.2009, 12:45

A без php как сделать пароль на страницу? Например если все будет не в web'е, а на винчестере, и нет никаких денверов и других php серверов.
Хочу сделать рассылку по почте, чтоб открывалось браузером, но в компьютере, и для разных людей разные пароли а не на сайте, но не у всех есть php на компьтерах.
Только чтоб в исходнике не отображался сам пароль иначе смысла в этом нет.
Надеюсь объяснил понятно.

13.10.2009, 13:53
Сообщение от nonofrost
A без php как сделать пароль на страницу?

а никак
можете конечно на javascript'e всё зашифровать
но знающему человеку - это не составит труда посмотреть

11.11.2009, 14:44

Единственным вариантом стало скомпилировать файл в exe, и отправлять таким образом клиентам непосредственно. Тогда расшифровать даже знающему человеку стало значительно труднее.

11.11.2009, 14:57
HTMLandPHP

nonofrost, запоролить без php можно директорию
подсказка

29.11.2009, 21:42

может еще кто-то знает как сделать платную регистрацию?:0082:
и еще знающие можете выложить javascript регистрации для html.:0018:

29.11.2009, 21:50
Сообщение от Sheps
может еще кто-то знает как сделать платную регистрацию?

определяетесь со способом приёма платежа
регистрируетесь в платёжных системах
скачиваете документацию на использование их интерфейсов платежей
например на php или asp пишете скрипт регистрации
активацию учётной записи делаете платной

Сообщение от Sheps
и еще знающие можете выложить javascript регистрации для html
врятли получится регистрация чисто на JS + HTML

29.11.2009, 21:53
Сообщение от Sheps
может еще кто-то знает как сделать платную регистрацию?

это обычная регистрация с активацией после оплаты

Сообщение от Sheps
и еще знающие можете выложить javascript регистрации для html.

такого не существует, т.к. любая регистрация должна сохранять данные на сервере, а используя только js это невозможно

03.02.2010, 09:32

Помогите, ГУРУ! Делаю сайт для себя (html, css, php, js) с чатом (чат закрытый). Система такова, что на сайте должны быть страницы для (не автоматической) регистрации посетителя (имя, фамилия, emal, пароль-обязательные поля) и восстановления пароля, а другая страница с активацией emal и пароля. Очень прошу, помогите! Очень надо работающий php скрипт и подробная инструкция по установке. Что бы при регистрации все данные шли админу на подтверждение и был виден ip регистрируемого, а при активации пароля был переход на чат. Я убила 9 дней для поиска подходящего скрипта (сама не профи, поэтому написать его не могу), голова кругом, но ничего походящего не нашла. Одна надежда на вас. Помогите, плииииз!

05.02.2010, 09:56

Ау! Люди! Хоть что-нибудь ответьте. Или форум умер?

05.02.2010, 12:20
Сообщение от Webmaster

 
session_start();
header("Content-Type: text/html; charset=cp1251");

function show_form($message) <
?>



Имя:



Пароль:



die();
>

//Проверка нажатия кнопки submit
if(!isset($_POST['subm'])) show_from('');
//Проверка на введенные данные
if(!isset($_POST['user']) OR !isset($_POST['pass']) OR empty($_POST['user']) OR empty($_POST['pass']))
show_form("Не правильная пара логин-пароль.");
// подключение к БД - соответственно прописываем свои данные доступа к базе данных
$connection = mysql_connect("localhost","","") ;
mysql_select_db('database') ;
// НЕ смог достучаться до БД
if (mysql_error()) die();

$user = mysql_escape_string($_POST['user']);
$pass = md5($_POST['pass']."ahha");

// Проверяем есть ли пользователь с таким логином и паролем
$result = mysql_query("SELECT `id` FROM `users` WHERE `login`='".$user."' AND `pass`='".$pass."'");

// если есть - впускаем
if(mysql_num_rows($result)==1)
$_SESSION['admin']=$adm;

// Если нет - пишем так.
else
show_form("Incorrect login-password.");

// Далее сообщение которое увидит вошедший пользователь
?>



Здравствуйте !
 
CREATE TABLE `users` (
`username` varchar(20) NOT NULL default '',
`pass` varchar(20) NOT NULL default ''
) ENGINE=MyISAM;

А когда я пользователя через Бд добавляю мне как ему пароль ставить ? Цифрами или в md5 ?

05.02.2010, 12:26
Запрос в БД

 
[COLOR=#3366ff]CREATE TABLE `users` (
`id` INT( 6 ) NOT NULL AUTO_INCREMENT ,
`nick` VARCHAR( 30 ) NOT NULL ,
`password` VARCHAR( 50 ) NOT NULL,
`email` VARCHAR( 50 ) NOT NULL ,
`icq` VARCHAR( 10 ) NOT NULL ,
`avatar` VARCHAR( 50 ) NOT NULL ,
`description` TEXT NOT NULL ,
`town` VARCHAR( 20 ) NOT NULL ,
`site` VARCHAR( 50 ) NOT NULL ,
`uniq_id` VARCHAR( 50 ) NOT NULL ,
`status` INT( 1 ) NOT NULL ,
`last_date` INT( 8 ) NOT NULL ,
`date` INT( 8 ) NOT NULL ,
PRIMARY KEY ( `id` )
) ENGINE = MYISAM[/COLOR]

Форма регистрации

Наверняка каждый из вас не раз проходил регистрацию и знает как неохота заполнять большое количество полей. Я предлагаю пойти на встречу пользователям и использовать только те данные, которые необходимы для осуществления регистрации: Ник пользователя, адрес электронной почты и пароль. Все остальное (если профиль будет расширенным) мы сможем изменить в личном кабинете.

registration.php

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

 
session_start();

@include("config.inc.php");
@include("functions.inc.php");

//Необходимо подключиться к БД
$link = mysql_connect($DBSERVER, $DBUSER, $DBPASS)
or die("Не могу подключиться" );
// сделать $DB текущей базой данных
mysql_select_db($DB, $link) or die ('Не могу выбрать БД');
 
if(!$_POST['do'] OR $_POST['do'] =='') //Генерируем шестизначный ключ для капчи
if($_SESSION['uid'] =='') < $_SESSION['uid'] = mt_rand(100000,999999); >

//Выводим форму
echo 'Регистрация';
echo'
';
echo 'Желаемый ник:
';
echo 'Пароль:
';
echo 'Ещё раз пароль:
';
echo 'Эл.адрес
';
echo '


';
echo '';
echo '
';

>
//Если данные отправлены 
if($_POST['do'] !='') //Начинаем проверять входящие данные
if($_POST['sid'] == $_SESSION['uid'])
//Создаем запрос к базе для проверки существования Пользователя

$nick = $_POST['nick'];
@mysql_query("SELECT * FROM users WHERE nick='".strtolower($nick)."'");
//Проверка результата запроса

if(mysql_affected_rows()==0) //Проверка ввведенных паролей

if($_POST['pass'] !='' AND $_POST['rpass'] !='' AND $_POST['pass'] === $_POST['rpass']) //Проверяем на валидность электронный адрес
if(checkmail($_POST['mail']) !== -1)
//Осуществляем регистарацию
//Генерируем uniq_id
$uniq_id = md5($_SERVER['REMOTE_ADDR'].$_SERVER['HTTP_USER_AGENT'].mktime());
$pass = $_POST['pass'];
$email = $_POST['mail'];
//Создаем запрос для записи данных в БД
$r = @mysql_query("INSERT INTO users VALUES(NULL,'".strtolower($nick)."','".md5($pass)."','".$email."','".$uniq_id."',0,'".date("dmY")."','".date("dmY")."')");

//После запроса отправляем письмо юзеру, для активации аккаунта
if($r)
// Для отправки e-mail в виде HTML устанавливаем необходимый mime-тип и кодировку
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=windows-1251' . "\r\n";

// Откуда пришло
$headers .= 'From:Сайт %sitename%' . "\r\n";

//Здесь укажите электронный адрес, куда будут уходить сообщения
$mailto = $email;
$subject = "Подтверждение регистарции на сайте";
$message = 'Для активации аккаунта пройдите по следующей ссылке
activation='.$uniq_id.'" target="_blank">http://АДРЕС_САЙТА/registration.php?activation='.$uniq_id.'';
$message .= 'или скопируйте ссылку в окно ввода адреса браузера и нажмите enter.';
//Отправляем сообщение
if(sendmail($mailto,$subject,$message,$headers) !== FALSE) echo 'Регистрация завершена, на введеный Вами e-mail было отправлено сообщение для активации аккаунта';
>
else
>
else
>
else [email protected]

href="registration.php"/>назад';>

>
else назад';>


>
else < echo 'Регистрация невозможна: Пользователь с таким именем уже существует
назад';>


session_destroy();
>
else < echo 'Регистрация невозможна: код подтверждения введен не верно
назад';>



>

Это наш главный блок, который производит проверку введенных данных. Помимо проверки электронного адреса на валидность и кода подтверждения, создается запрос , проверяющий наличие ник-нейма в базе. В случае совпадения выводим сообщение о том, что юзер с таким именем существует.Здесь я немного сократил запрос, а точнее записал в компактной форме, т.е.:
@mysql_query(»SELECT nick FROM users WHERE nick=’».$nick.»‘»);
ЗАПРОС(»ВЫБРАТЬ nick ИЗ users ГДЕ nick = $nick»);
После выполнения запроса функцией mysql_affected_rows() узнаем количество затронутых рядов. Если в таблице уже есть юзер с таким ником, то мы просто выводим соответсвующее сообщение. Если же совпадения не найдены, переходим к проверке паролей. Ни одно заполняемое поле не должно быть пустым, особенно пароли.
Далее проверяем электронный адрес на валидность. Если условие возвращает TRUE, то переходим непосредственно к регистрации пользователя.
Так как мы используем регистрацию с активацией профиля, нам необходимо сгенерировать уникальный идентификатор пользователя. Он будет состоять из его IP-адреса, типа браузера и значения возвращаемые функцией mk_time(). Склеяв данные в одну строку мы закодируем её функцией md5().
Создаем запрос для записи значений в БД.

Единственное стоит обратить на то какие данные вносятся в БД. Здесь status обязательно равен 0. Далее создаем условие, котрое проверяет результат этого запроса. Если запрос был обработан, необходимо составить сообщение и отправить на введенный электронный адрес ссылку с активацией.
Сообщение компонуем из $subject – темы письма, $message – самого сообщения и заголовков $headers.
$message содержит ссылку, которая ведет на registration.php и передает GET-параметром уникальный идентификатор сгенерированный выше. Что произойдет когда пользователь перейдет по ссылке мы рассмотрим ниже.

 
//Модуль отвечающий за активацию аккаунта

if($_GET['activation'] AND $_GET['activation']!='')
$uniq_id = $_GET['activation'];
//Создаем запрос
$r=@mysql_query("UPDATE users SET status=1 WHERE uniq_id='".$uniq_id."' AND status=0");
if($r) Ваша учетная запись активирована.
Теперь вы можете войти на сайт используя данные

указанные при регистрации';>

else

>
?>

Хочу обратить внимание на то что при отправке письма мы не передавали не имя пользователя , ни пароля. Это дополнительная безопасность, которая исключит похищение данных от аккаунта в случае взлома почты или других непредвиденных ситуаций. Поэтому мы будем полностью опираться на уникальный идентификатор пользователя.
Создавая запрос мы устанавливаем status равный единице, пользователю у которого соответствующий uniq_id и статус равный нулю. Если запрос был выполнен, выводим сообщение об успешной активации. Теперь юзер может использовать свои данные для авторизации
Авторизация пользователя.

Так как многие от авторизации преследует одну цель, то мы разберем вариант, когда не авторизованный пользователь не имеет доступа к странице.
Сам принцип авторизации достаточно простой и применим к небольшим проектам. Главная особенность – это работа с сессиями, проверка их существования и сверка с данными из БД.
По умолчанию я буду использовать страницу index.php , на которой будет что-либо скрыто.
index.php

 
session_start();
//Поключаем конфиг
include("config.inc.php");

//Необходимо подключиться к БД
$link = mysql_connect($DBSERVER, $DBUSER, $DBPASS)
or die("Не могу подключиться" );
// сделать $DB текущей базой данных
mysql_select_db($DB, $link) or die ('Не могу выбрать БД');
//Если нет сессий 
if(md5(crypt($_SESSION['user'],$_SESSION['password'])) != $_SESSION['SID']) //Если кнопка не нажата, отображаем форму
if(!$_POST['do'])
echo '






';

>
//Если кнопка нажата 
if($_POST['do']) //Проверяем данные
$login = $_POST['login'];
$upass = $_POST['password'];
if($login !='' AND $upass !='') //Создаем запрос
$q1=mysql_query("SELECT * FROM users WHERE nick='".$login."' AND password='".md5($upass)."' AND status=1");

//Проверяем существует ли хоть одна запись
if(mysql_num_rows($q1)===1) //Если есть, то создаем сессии и перенаправляем на эту страницу
$r=mysql_fetch_array($q1);
$_SESSION['user'] = $r['nick'];
$_SESSION['password'] = $r['password'];

$_SESSION['SID'] = md5(crypt($r['nick'],$r['password']));

@Header("Location: index.php");
>
else
>
>
else
>
else  
$q2 = @mysql_query("SELECT * FROM users WHERE nick='".$_SESSION['user']."' AND password='".$_SESSION['password']."' AND status=1");
if(@mysql_num_rows($q2)==1) <
$r2 = @mysql_fetch_array($q2);

echo 'Вы: '.ucfirst($r2['nick']).'
';
echo 'главная ';
echo 'загрузки
';

if($_GET['page'] !='') @include("tpl/".$_GET['page'].".php");
>
else < @include("tpl/default.php");>



echo '

выход';
>
>
 
if($_GET['exit'])
?>

Если вы заметили, то в предыдущем фрагменте есть ссылочка index.php?exit=1. Если $_GET['exit'] существует, то мы уничтожаем сессию , стираем $_GET['exit'], закрываем соеденение с БД и делаем редирект на главную. Это позволит качественно «отлогиниться».
Шаблоны.

Файлы шаблонов будут лежать в папке tpl на сервере, поэтому не забудьте её создать и поместить в неё шаблон, который грузиться по умолчанию.

default.php

 

echo 'Этот текст будет отображаться по умолчанию.
В шаблоне можно использовать любой код. Все шаблоны должны иметь расширение php';

?>

Файл конфигурации.

Файл конфигурации содержит в себе необходимые данные для подключения к БД.

config.inc.php

 

//Сервер, в большинстве случаев менять не требуется
$DBSERVER = "localhost";
//Пользователь и пароль
$DBUSER = "root";
$DBPASS = "12345678";//Ваш пароль
//База данных
$DB = "test";

?>

Файл функций

Файл содержит 2 функции. Первая для проверки e-mail’а на корректность, а вторая для отправки почты.
functions.inc.php

 

function checkmail($mail) // режем левые символы и крайние пробелы
$mail=trim($mail); // функцию pregtrim() возьмите выше в примере
// если пусто - выход
if (strlen($mail)==0) return -1;
if (!preg_match("/^[a-z0-9_-]+(\.)+([a-z0-9_-])@(([a-z0-9-]+\.)+(com|net|org|mil|".
"edu|gov|arpa|info|biz|inc|name|[a-z])|[0-9]\.[0-9]\.[0-".
"9]\.[0-9])$/is",$mail))
return -1;
return $mail;
>

function sendmail($mail,$subject,$message,$headers)
if(mail($mail,$subject,$message,$headers)) < return TRUE;>
else

>

?>

Если ты гуру то ты сам переделаешь или поймёшь что и как .

05.02.2010, 12:36

СПАСИБО. Это я к вам обращалась ГУРУ. Я сама в рядах осликов. ОГРОМНЕЙШОЕ СПАСИБО. Буду пробовать.

13.03.2010, 13:16

Webmaster, Здравствуйте! Хочу создать базу данных в mysql, кот будет содержать имя и пароль клиентов. как осуществить связь с сайтом. Заранее благодарен!

13.03.2010, 14:58
Сообщение от alokey

Webmaster, Здравствуйте! Хочу создать базу данных в mysql, кот будет содержать имя и пароль клиентов. как осуществить связь с сайтом. Заранее благодарен!

Между строк: напишите мне методы соединения с мускульной базой.
Некорректно поставленный вопрос.

13.03.2010, 15:33

У меня задача такая: просто осуществить зарегистрированному пользователю доступ к сайту. Я думаю в базе должны быть четыре поля счечик, логин, пароль и реальное имя пользователя.
Подскажите каким методом и где-какой код должен находится., ато я ниче понять не могу

где должна находится сама база данных, вообще иерархию файлов как что и где(если можно).

13.03.2010, 19:15

база должна находиться на сервере mySQL (Microsoft SQL, Oracle или каком Вам нравиться). Сервер должен быть либо дан хостером, либо ищите внешний, но заметьте, при внешнем скорость работы будет ниже. При входе на сайт пользователю надо вывести форму для ввода логина и пароля и ссылку для регистрации. После ввода логина и пароля надо обработчиком формы (путь к которому находиться в атрибуте action выведенной формы) проверить есть-ли в базе данных пользоватеть с таким логином и паролем, если есть записать в сессию его реальное имя, если Вы его потом собираетесь где-то вывести на сайте, записать переменную logged = true, которая будет означать, что пользователь вошел, и id этого пользователя из базы данных. при открытии сайта проверять, есть ли в сесии пользователя все эти данные, если нет - форма для входа, если есть - добро пожаловать на сайт.

Текущее время: 09:46 . Часовой пояс GMT +2.

Powered by vBulletin™ Version 4.1.3 Copyright © 2023 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *