Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
PHP обучение на примерах - Кухарчик А..pdf
Скачиваний:
139
Добавлен:
24.05.2014
Размер:
24 Мб
Скачать
☆

134

Программирование на РНР

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

<аhref=guest.txt>apxив</a>

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

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

Чат

Технология создания

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

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

Очень многие Web-мастеры мечтают сделать для своих посетителей хороший чат. Как правило, Web-мастеры идут проторенным путем, ищут в интернете исходные коды чатов и размещают их у себя на сервере. Непременное условие — обязательное наличие на сервере поддержки одного из языков программирования. Как правило, чаты предпочитают делать, используя CGI (например, на языке Perl). Такие чаты получаются достаточно быстрыми и надежными.

Чат

 

135

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

Можно, конечно, пойти по легкому пути. Например, открыть свой чат на каком-нибудь бесплатном сервере. Разработка такого чата сводится к настройке уже готового скрипта: выбору цвета, расположения фреймов (см. ниже) и другим мелким деталям.

Однако есть, как всегда, и отрицательные стороны такого решения. Никто просто так вам не даст пользоваться своим чатом — придется «расплачиваться» тем, что в вашем чате будут показываться чьи-то баннеры. И нет гарантии, что чат не закроют. Но это единственный способ сделать чат для тех, у кого хос- тинг-провайдер не обеспечивает поддержку CGI.

Если же ваш сервер работает с CGI или РНР, вы легко можете найти в интернете массу хороших и не очень скриптов чатов и разместить их у себя на сайте, тогда вы уже ни от кого не будете зависеть. Но есть недостатки и у этого способа. Поскольку исходные коды таких чатов общедоступны, у них почти всегда обнаруживается какая-нибудь уязвимость, позволяющая злоумышленникам «взламывать» ваш любимый чат.

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

Если вас это не устраивает, придется идти по трудному и сложному пути создания собственного чата, чем мы и попробуем заняться.

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

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

136

Программирование на РНР

лению алгоритмов расшифровки. Значит, вам придется разрабатывать свой собственный алгоритм шифрования паролей пользователей с условием невозможности расшифровки за разумный промежуток времени (надеюсь, ФСБ или ФБР не будут «взламывать» ваш чат).

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

Выход из такой ситуации — не хранить незашифрованные пароли вообще.

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

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

Все очень просто и элегантно. Я опишу на примере Windows 2000, в которой реализован примерно следующий алгоритм. При регистрации пользователь вводит свой пароль, который обраба-

Чат

 

137

тывается специальной функцией необратимого шифрования. Результат заносится в базу паролей вместе с учетными записями (имя пользователя, описание и т.д.). Когда пользователь входит в систему в следующий раз, Windows опять шифрует введенный пароль своей стандартной функцией и сравнивает результат с тем, который хранится у нее в базе данных паролей. Если результат шифрования введенного пароля и хранящегося в базе являются идентичными строками, пользователь авторизован, если нет — ошибка ввода пароля.

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

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

Таким образом, очень легко «взломать» нестойкий пароль. О стойкости пароля сказано уже очень много до меня, но вкратце смысл таков: ни в коем случае нельзя применять для пароля смысловое сочетание букв. Другими словами, пароль должен казаться полной бессмыслицей постороннему человеку. Такой пароль гораздо труднее подобрать методом прямого перебора и практически невозможно перебором слов по специальным словарям. Очень хорошо, если в пароле присутствуют знаки препинания, чередуются маленькие и большие буквы, используются цифры и т.д. Рекомендуйте это своим посетителям.

Кроме авторизации очень важным является пункт настройки чата. Как правило, применяются три варианта настройки: на-

138

 

Программирование на РНР

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

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

Кроме загрузки по умолчанию, желательно предусмотреть гостевой вход, при котором не потребуется даже регистрация. Сделать это проще всего так: создать пользователя с именем Гость, выбрав для пароля, например, слово guest, и посетителю, входящему без ввода учетных данных (логина и пароля), загружать именно эту учетную запись.

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

Как правило, все параметры настройки, введенные ник и пароль, передаются методом POST (CM. приложение 5) в загрузчик, где после соответствующей обработки в браузер загружаются несколько фреймов .

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

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

1 Фреймы — подокна в окне сайта. Информация в одном фрейме размещается независимо от другого и может иметь свою автономную полосу прокрутки.

(Примеч. ред.)

Чат

 

139

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

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

Кроме того, надо проверять и корректировать все введенные пользователем данные. Не рассчитывайте, что переменные, переданные вашему загрузчику методом POST, не смогут принять непредусмотренное вами значение. Ведь можно воспользоваться еще и методом GET (CM. приложение 5), а это значит, что вашему загрузчику могут такое передать..! По этой причине обрабатывать полученные переменные необходимо по всем правилам. Другими словами, всегда проверяйте, соответствует ли полученная переменная нужному диапазону, и если нет — лучше всего присвоить ей стандартное значение. Кстати, желательно контролировать метод передачи данных. Если вы применяете метод POST, проверьте переменную окружения $QUERY_STRING. ЕСЛИ она не пустая, значит, вашему загрузчику пытаются что-то передать еще и при помощи метода GET. ЭТИ ПОПЫТКИ нужно пресекать.

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

140

 

Программирование на РНР

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

Информацию о цвете и настройках можно передать как обычно, методом GET. Она, как правило, не влияет на существенные настройки чата и все равно доступна для изменения. Есть возможность передавать все данные с помощью cookie. Это самый легкий метод плох тем, что посетитель без поддержки cookie или с отключенной такой поддержкой в настройках браузера не сможет пользоваться вашим чатом. Изменить файл cookie на диске можно, но это уже несколько сложнее, и специалист, который сможет это сделать, вряд ли заинтересуется вашим чатом. У него и так работы хватает :-)

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

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

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

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

Чат

 

141

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

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

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

Конечно, и этот способ авторизации не абсолютно надежен, ведь все, что сделал один человек, второй может исследовать и переделать. Однако мне такая защита кажется достаточной.

Описанная методика не очень сложна, но накладывает некоторые ограничения на сервер. Если учетных записей достаточно много, нагрузка будет довольно большая. Можно пойти более легким путем — авторизовывать пользователя по идентификатору не каждый раз, а только один, в самом начале. Дальше можно передавать более простой идентификатор методом POST (например, номер учетной записи в базе данных). Однако учтите, что это дает «взломщику» еще одну возможность несанкционированного проникновения в ваш чат, что нежелательно.

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

142

Программирование на РНР

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

Следующая часть чата — окно для ввода сообщений. Именно здесь необходимо проверять авторизацию пользователя по цифровому идентификатору. Авторизация будет проводиться всякий раз, когда сообщение будет отправляться в чат после нажатия кнопки «Отправить».

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

В данном фрейме можно также организовать выбор цвета и типа шрифта, вывод иконок и т.д.

Самое сложное — применить технологию, при помощи которой определяется, кто находится в чате в данный момент. Если отказаться от этого сервиса, все значительно упростится, и чат очень слабо будет загружать сервер. Но ведь это неинтересно, так что этот вариант мы пропустим и перейдем к следующему, самому сложному в отношении программирования фрейму. В нем можно увидеть, кто и сколько времени присутствует в чате. Для реализации данной возможности необходимо и в этом фрейме авторизовать посетителя по уникальному идентификатору, причем делать это с определенной периодичностью. Ведь нужно проверять, не появился ли в чате новый посетитель и не покинул ли чат кто-то из присутствующих. Чем чаще такие проверки, тем больше нагрузка на сервер. Можно ограничиться одной авторизацией, а дальше передавать простой идентификатор по методу GET. Этот идентификатор можно подделать, однако программа из предыдущего фрейма, которая реализует полноценную проверку данных, не позволит вывести сообщения от пользователя с поддельным идентификатором.

Чат

 

143

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

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

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

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

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

Соседние файлы в предмете Программирование